From 06161b5aad20c4306ca4b04205bea2c81078e3b1 Mon Sep 17 00:00:00 2001 From: chyyran Date: Tue, 7 Feb 2023 22:02:08 -0500 Subject: [PATCH] rt: make scale framebuffers a lot nicer to use --- librashader-runtime-d3d11/src/filter_chain.rs | 5 +- librashader-runtime-d3d11/src/framebuffer.rs | 6 +- librashader-runtime-d3d12/src/filter_chain.rs | 9 +- librashader-runtime-d3d12/src/framebuffer.rs | 6 +- .../src/filter_chain/filter_impl.rs | 5 +- librashader-runtime-gl/src/gl/framebuffer.rs | 6 +- librashader-runtime-vk/src/filter_chain.rs | 13 ++- librashader-runtime-vk/src/texture.rs | 10 +- librashader-runtime/src/lib.rs | 3 +- librashader-runtime/src/scaling.rs | 93 ++++++++++++------- 10 files changed, 95 insertions(+), 61 deletions(-) diff --git a/librashader-runtime-d3d11/src/filter_chain.rs b/librashader-runtime-d3d11/src/filter_chain.rs index bb802f5..3bad316 100644 --- a/librashader-runtime-d3d11/src/filter_chain.rs +++ b/librashader-runtime-d3d11/src/filter_chain.rs @@ -26,7 +26,7 @@ use crate::{error, util, D3D11OutputView}; use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; use librashader_runtime::binding::{BindingUtil, TextureInput}; use librashader_runtime::quad::{QuadType, IDENTITY_MVP}; -use librashader_runtime::scaling::scale_framebuffers; +use librashader_runtime::scaling::ScaleFramebuffer; use librashader_runtime::uniforms::UniformStorage; use rayon::prelude::*; use windows::Win32::Graphics::Direct3D11::{ @@ -455,12 +455,13 @@ impl FilterChainD3D11 { let mut source = original.clone(); // rescale render buffers to ensure all bindings are valid. - scale_framebuffers::<(), _, _, _>( + OwnedFramebuffer::scale_framebuffers( source.size(), viewport.output.size, &mut self.output_framebuffers, &mut self.feedback_framebuffers, passes, + None, )?; let passes_len = passes.len(); diff --git a/librashader-runtime-d3d11/src/framebuffer.rs b/librashader-runtime-d3d11/src/framebuffer.rs index 45c42e3..fcebdbd 100644 --- a/librashader-runtime-d3d11/src/framebuffer.rs +++ b/librashader-runtime-d3d11/src/framebuffer.rs @@ -4,7 +4,7 @@ use crate::texture::D3D11InputView; use crate::util::d3d11_get_closest_format; use librashader_common::{ImageFormat, Size}; use librashader_presets::Scale2D; -use librashader_runtime::scaling::{MipmapSize, ScaleableFramebuffer, ViewportSize}; +use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize}; use windows::core::Interface; use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D; use windows::Win32::Graphics::Direct3D11::{ @@ -252,7 +252,7 @@ pub const fn default_viewport(size: Size) -> D3D11_VIEWPORT { } } -impl ScaleableFramebuffer for OwnedFramebuffer { +impl ScaleFramebuffer for OwnedFramebuffer { type Error = FilterChainError; type Context = (); @@ -263,7 +263,7 @@ impl ScaleableFramebuffer for OwnedFramebuffer { viewport_size: &Size, source_size: &Size, should_mipmap: bool, - _context: Self::Context, + _context: &Self::Context, ) -> Result, Self::Error> { self.scale(scaling, format, viewport_size, source_size, should_mipmap) } diff --git a/librashader-runtime-d3d12/src/filter_chain.rs b/librashader-runtime-d3d12/src/filter_chain.rs index 1647fdf..289e5c9 100644 --- a/librashader-runtime-d3d12/src/filter_chain.rs +++ b/librashader-runtime-d3d12/src/filter_chain.rs @@ -46,7 +46,7 @@ use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_UNKNOWN; use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject}; use windows::Win32::System::WindowsProgramming::INFINITE; -use librashader_runtime::scaling::{scale_framebuffers_with_context_callback, MipmapSize}; +use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer}; use rayon::prelude::*; const MIPMAP_RESERVED_WORKHEAP_DESCRIPTORS: usize = 1024; @@ -593,14 +593,13 @@ impl FilterChainD3D12 { ); // rescale render buffers to ensure all bindings are valid. - scale_framebuffers_with_context_callback::<(), _, _, _, _>( + OwnedImage::scale_framebuffers( source.size(), viewport.output.size, &mut self.output_framebuffers, &mut self.feedback_framebuffers, passes, - (), - |index: usize, pass: &FilterPass, output: &OwnedImage, feedback: &OwnedImage| { + Some(&mut |index, pass, output, feedback| { // refresh inputs self.common.feedback_textures[index] = Some(feedback.create_shader_resource_view( &mut self.staging_heap, @@ -614,7 +613,7 @@ impl FilterChainD3D12 { )?); Ok(()) - }, + }), )?; let passes_len = passes.len(); diff --git a/librashader-runtime-d3d12/src/framebuffer.rs b/librashader-runtime-d3d12/src/framebuffer.rs index 038b5e3..d46bb34 100644 --- a/librashader-runtime-d3d12/src/framebuffer.rs +++ b/librashader-runtime-d3d12/src/framebuffer.rs @@ -5,7 +5,7 @@ use crate::util::d3d12_get_closest_format; use crate::{error, util}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_presets::Scale2D; -use librashader_runtime::scaling::{MipmapSize, ScaleableFramebuffer, ViewportSize}; +use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize}; use std::ops::Deref; use windows::Win32::Foundation::RECT; use windows::Win32::Graphics::Direct3D12::{ @@ -306,7 +306,7 @@ impl OwnedImage { } } -impl ScaleableFramebuffer for OwnedImage { +impl ScaleFramebuffer for OwnedImage { type Error = FilterChainError; type Context = (); @@ -317,7 +317,7 @@ impl ScaleableFramebuffer for OwnedImage { viewport_size: &Size, source_size: &Size, should_mipmap: bool, - _context: Self::Context, + _context: &Self::Context, ) -> Result, Self::Error> { self.scale(scaling, format, viewport_size, source_size, should_mipmap) } diff --git a/librashader-runtime-gl/src/filter_chain/filter_impl.rs b/librashader-runtime-gl/src/filter_chain/filter_impl.rs index 179a6b1..f376a90 100644 --- a/librashader-runtime-gl/src/filter_chain/filter_impl.rs +++ b/librashader-runtime-gl/src/filter_chain/filter_impl.rs @@ -21,7 +21,7 @@ use librashader_reflect::reflect::semantics::{BindingMeta, ShaderSemantics, Unif use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; use librashader_reflect::reflect::ReflectShader; use librashader_runtime::binding::BindingUtil; -use librashader_runtime::scaling::scale_framebuffers; +use librashader_runtime::scaling::ScaleFramebuffer; use rustc_hash::FxHashMap; use spirv_cross::spirv::Decoration; use std::collections::VecDeque; @@ -380,12 +380,13 @@ impl FilterChainImpl { let mut source = original; // rescale render buffers to ensure all bindings are valid. - scale_framebuffers::( + >::scale_framebuffers( source.image.size, viewport.output.size, &mut self.output_framebuffers, &mut self.feedback_framebuffers, passes, + None, )?; let passes_len = passes.len(); diff --git a/librashader-runtime-gl/src/gl/framebuffer.rs b/librashader-runtime-gl/src/gl/framebuffer.rs index e35446c..669a42f 100644 --- a/librashader-runtime-gl/src/gl/framebuffer.rs +++ b/librashader-runtime-gl/src/gl/framebuffer.rs @@ -5,7 +5,7 @@ use crate::texture::InputTexture; use gl::types::{GLenum, GLuint}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_presets::Scale2D; -use librashader_runtime::scaling::ScaleableFramebuffer; +use librashader_runtime::scaling::ScaleFramebuffer; /// A handle to an OpenGL FBO and its backing texture with format and size information. /// @@ -94,7 +94,7 @@ impl Drop for Framebuffer { } } // -impl ScaleableFramebuffer for Framebuffer { +impl ScaleFramebuffer for Framebuffer { type Error = FilterChainError; type Context = (); @@ -105,7 +105,7 @@ impl ScaleableFramebuffer for Framebuffer { viewport_size: &Size, source_size: &Size, should_mipmap: bool, - _context: Self::Context, + _context: &Self::Context, ) -> Result> { self.scale::(scaling, format, viewport_size, source_size, should_mipmap) } diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index 86a7ea1..34ab528 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -30,7 +30,7 @@ use std::collections::VecDeque; use std::path::Path; use std::sync::Arc; -use librashader_runtime::scaling::scale_framebuffers_with_context_callback; +use librashader_runtime::scaling::ScaleFramebuffer; use rayon::prelude::*; /// A Vulkan device and metadata that is required by the shader runtime. @@ -614,27 +614,30 @@ impl FilterChainVulkan { ); // rescale render buffers to ensure all bindings are valid. - scale_framebuffers_with_context_callback::<(), _, _, _, _>( + OwnedImage::scale_framebuffers_with_context( source.image.size, viewport.output.size, &mut self.output_framebuffers, &mut self.feedback_framebuffers, passes, - Some(OwnedImageLayout { + &Some(OwnedImageLayout { dst_layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL, dst_access: vk::AccessFlags::SHADER_READ, src_stage: vk::PipelineStageFlags::TOP_OF_PIPE, dst_stage: vk::PipelineStageFlags::FRAGMENT_SHADER, cmd, }), - |index: usize, pass: &FilterPass, output: &OwnedImage, feedback: &OwnedImage| { + Some(&mut |index: usize, + pass: &FilterPass, + output: &OwnedImage, + feedback: &OwnedImage| { // refresh inputs self.common.feedback_inputs[index] = Some(feedback.as_input(pass.config.filter, pass.config.wrap_mode)); self.common.output_inputs[index] = Some(output.as_input(pass.config.filter, pass.config.wrap_mode)); Ok(()) - }, + }), )?; let passes_len = passes.len(); diff --git a/librashader-runtime-vk/src/texture.rs b/librashader-runtime-vk/src/texture.rs index 09eb9ac..e3dd7bd 100644 --- a/librashader-runtime-vk/src/texture.rs +++ b/librashader-runtime-vk/src/texture.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use crate::error::FilterChainError; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_presets::Scale2D; -use librashader_runtime::scaling::{MipmapSize, ScaleableFramebuffer, ViewportSize}; +use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize}; pub struct OwnedImage { pub device: Arc, @@ -20,7 +20,7 @@ pub struct OwnedImage { pub levels: u32, } -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct OwnedImageLayout { pub(crate) dst_layout: vk::ImageLayout, pub(crate) dst_access: vk::AccessFlags, @@ -536,7 +536,7 @@ impl AsRef for InputImage { } } -impl ScaleableFramebuffer for OwnedImage { +impl ScaleFramebuffer for OwnedImage { type Error = FilterChainError; type Context = Option; @@ -547,7 +547,7 @@ impl ScaleableFramebuffer for OwnedImage { viewport_size: &Size, source_size: &Size, should_mipmap: bool, - context: Self::Context, + context: &Self::Context, ) -> Result, Self::Error> { self.scale( scaling, @@ -555,7 +555,7 @@ impl ScaleableFramebuffer for OwnedImage { viewport_size, source_size, should_mipmap, - context, + context.clone(), ) } } diff --git a/librashader-runtime/src/lib.rs b/librashader-runtime/src/lib.rs index bdb1160..3db1f14 100644 --- a/librashader-runtime/src/lib.rs +++ b/librashader-runtime/src/lib.rs @@ -26,7 +26,8 @@ pub mod ringbuffer; /// Generic implementation of semantics binding. pub mod binding; -/// VBO helper utilities +/// VBO helper utilities. pub mod quad; +/// Filter pass helpers and common traits. pub mod filter_pass; diff --git a/librashader-runtime/src/scaling.rs b/librashader-runtime/src/scaling.rs index d27f821..6bf79c2 100644 --- a/librashader-runtime/src/scaling.rs +++ b/librashader-runtime/src/scaling.rs @@ -96,9 +96,9 @@ where } /// Trait for owned framebuffer objects that can be scaled. -pub trait ScaleableFramebuffer { +pub trait ScaleFramebuffer { type Error; - type Context: Copy; + type Context; /// Scale the framebuffer according to the provided parameters, returning the new size. fn scale( &mut self, @@ -107,49 +107,76 @@ pub trait ScaleableFramebuffer { viewport_size: &Size, source_size: &Size, should_mipmap: bool, - context: Self::Context, + context: &Self::Context, ) -> Result, Self::Error>; -} -/// Scale framebuffers according to the pass configs, source and viewport size. -#[inline(always)] -pub fn scale_framebuffers( - source_size: Size, - viewport_size: Size, - output: &mut [F], - feedback: &mut [F], - passes: &[P], -) -> Result<(), E> -where - F: ScaleableFramebuffer, - P: FilterPassMeta, -{ - scale_framebuffers_with_context_callback( - source_size, - viewport_size, - output, - feedback, - passes, - (), - |_, _, _, _| Ok(()), - ) + /// Scale framebuffers with default context. + #[inline(always)] + fn scale_framebuffers

( + source_size: Size, + viewport_size: Size, + output: &mut [Self], + feedback: &mut [Self], + passes: &[P], + callback: Option<&mut dyn FnMut(usize, &P, &Self, &Self) -> Result<(), Self::Error>>, + ) -> Result<(), Self::Error> + where + Self: Sized, + Self::Context: Default, + P: FilterPassMeta, + { + scale_framebuffers_with_context_callback::( + source_size, + viewport_size, + output, + feedback, + passes, + &Self::Context::default(), + callback, + ) + } + + /// Scale framebuffers with user provided context. + #[inline(always)] + fn scale_framebuffers_with_context

( + source_size: Size, + viewport_size: Size, + output: &mut [Self], + feedback: &mut [Self], + passes: &[P], + context: &Self::Context, + callback: Option<&mut dyn FnMut(usize, &P, &Self, &Self) -> Result<(), Self::Error>>, + ) -> Result<(), Self::Error> + where + Self: Sized, + P: FilterPassMeta, + { + scale_framebuffers_with_context_callback::( + source_size, + viewport_size, + output, + feedback, + passes, + context, + callback, + ) + } } /// Scale framebuffers according to the pass configs, source and viewport size /// passing a context into the scale function and a callback for each framebuffer rescale. #[inline(always)] -pub fn scale_framebuffers_with_context_callback( +fn scale_framebuffers_with_context_callback( source_size: Size, viewport_size: Size, output: &mut [F], feedback: &mut [F], passes: &[P], - context: C, - mut callback: impl FnMut(usize, &P, &F, &F) -> Result<(), E>, + context: &C, + mut callback: Option<&mut dyn FnMut(usize, &P, &F, &F) -> Result<(), E>>, ) -> Result<(), E> where - F: ScaleableFramebuffer, - C: Copy, + F: ScaleFramebuffer, P: FilterPassMeta, { assert_eq!(output.len(), feedback.len()); @@ -180,7 +207,9 @@ where target_size = next_size; - callback(index, pass, &output[index], &feedback[index])?; + if let Some(callback) = callback.as_mut() { + callback(index, pass, &output[index], &feedback[index])?; + } } Ok(())