rt: make scale framebuffers a lot nicer to use
This commit is contained in:
parent
45dbdc6157
commit
06161b5aad
|
@ -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();
|
||||
|
|
|
@ -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<u32>) -> D3D11_VIEWPORT {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> ScaleableFramebuffer<T> for OwnedFramebuffer {
|
||||
impl ScaleFramebuffer for OwnedFramebuffer {
|
||||
type Error = FilterChainError;
|
||||
type Context = ();
|
||||
|
||||
|
@ -263,7 +263,7 @@ impl<T> ScaleableFramebuffer<T> for OwnedFramebuffer {
|
|||
viewport_size: &Size<u32>,
|
||||
source_size: &Size<u32>,
|
||||
should_mipmap: bool,
|
||||
_context: Self::Context,
|
||||
_context: &Self::Context,
|
||||
) -> Result<Size<u32>, Self::Error> {
|
||||
self.scale(scaling, format, viewport_size, source_size, should_mipmap)
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<T> ScaleableFramebuffer<T> for OwnedImage {
|
||||
impl ScaleFramebuffer for OwnedImage {
|
||||
type Error = FilterChainError;
|
||||
type Context = ();
|
||||
|
||||
|
@ -317,7 +317,7 @@ impl<T> ScaleableFramebuffer<T> for OwnedImage {
|
|||
viewport_size: &Size<u32>,
|
||||
source_size: &Size<u32>,
|
||||
should_mipmap: bool,
|
||||
_context: Self::Context,
|
||||
_context: &Self::Context,
|
||||
) -> Result<Size<u32>, Self::Error> {
|
||||
self.scale(scaling, format, viewport_size, source_size, should_mipmap)
|
||||
}
|
||||
|
|
|
@ -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<T: GLInterface> FilterChainImpl<T> {
|
|||
let mut source = original;
|
||||
|
||||
// rescale render buffers to ensure all bindings are valid.
|
||||
scale_framebuffers::<T::FramebufferInterface, _, _, _>(
|
||||
<Framebuffer as ScaleFramebuffer<T::FramebufferInterface>>::scale_framebuffers(
|
||||
source.image.size,
|
||||
viewport.output.size,
|
||||
&mut self.output_framebuffers,
|
||||
&mut self.feedback_framebuffers,
|
||||
passes,
|
||||
None,
|
||||
)?;
|
||||
|
||||
let passes_len = passes.len();
|
||||
|
|
|
@ -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<T: FramebufferInterface> ScaleableFramebuffer<T> for Framebuffer {
|
||||
impl<T: FramebufferInterface> ScaleFramebuffer<T> for Framebuffer {
|
||||
type Error = FilterChainError;
|
||||
type Context = ();
|
||||
|
||||
|
@ -105,7 +105,7 @@ impl<T: FramebufferInterface> ScaleableFramebuffer<T> for Framebuffer {
|
|||
viewport_size: &Size<u32>,
|
||||
source_size: &Size<u32>,
|
||||
should_mipmap: bool,
|
||||
_context: Self::Context,
|
||||
_context: &Self::Context,
|
||||
) -> Result<Size<u32>> {
|
||||
self.scale::<T>(scaling, format, viewport_size, source_size, should_mipmap)
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<ash::Device>,
|
||||
|
@ -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<InputImage> for InputImage {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> ScaleableFramebuffer<T> for OwnedImage {
|
||||
impl ScaleFramebuffer for OwnedImage {
|
||||
type Error = FilterChainError;
|
||||
type Context = Option<OwnedImageLayout>;
|
||||
|
||||
|
@ -547,7 +547,7 @@ impl<T> ScaleableFramebuffer<T> for OwnedImage {
|
|||
viewport_size: &Size<u32>,
|
||||
source_size: &Size<u32>,
|
||||
should_mipmap: bool,
|
||||
context: Self::Context,
|
||||
context: &Self::Context,
|
||||
) -> Result<Size<u32>, Self::Error> {
|
||||
self.scale(
|
||||
scaling,
|
||||
|
@ -555,7 +555,7 @@ impl<T> ScaleableFramebuffer<T> for OwnedImage {
|
|||
viewport_size,
|
||||
source_size,
|
||||
should_mipmap,
|
||||
context,
|
||||
context.clone(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -96,9 +96,9 @@ where
|
|||
}
|
||||
|
||||
/// Trait for owned framebuffer objects that can be scaled.
|
||||
pub trait ScaleableFramebuffer<T> {
|
||||
pub trait ScaleFramebuffer<T = ()> {
|
||||
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<T> {
|
|||
viewport_size: &Size<u32>,
|
||||
source_size: &Size<u32>,
|
||||
should_mipmap: bool,
|
||||
context: Self::Context,
|
||||
context: &Self::Context,
|
||||
) -> Result<Size<u32>, Self::Error>;
|
||||
}
|
||||
|
||||
/// Scale framebuffers according to the pass configs, source and viewport size.
|
||||
#[inline(always)]
|
||||
pub fn scale_framebuffers<T, F, E, P>(
|
||||
source_size: Size<u32>,
|
||||
viewport_size: Size<u32>,
|
||||
output: &mut [F],
|
||||
feedback: &mut [F],
|
||||
passes: &[P],
|
||||
) -> Result<(), E>
|
||||
where
|
||||
F: ScaleableFramebuffer<T, Context = (), Error = E>,
|
||||
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<P>(
|
||||
source_size: Size<u32>,
|
||||
viewport_size: Size<u32>,
|
||||
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::<T, Self, Self::Error, Self::Context, _>(
|
||||
source_size,
|
||||
viewport_size,
|
||||
output,
|
||||
feedback,
|
||||
passes,
|
||||
&Self::Context::default(),
|
||||
callback,
|
||||
)
|
||||
}
|
||||
|
||||
/// Scale framebuffers with user provided context.
|
||||
#[inline(always)]
|
||||
fn scale_framebuffers_with_context<P>(
|
||||
source_size: Size<u32>,
|
||||
viewport_size: Size<u32>,
|
||||
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::<T, Self, Self::Error, Self::Context, _>(
|
||||
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<T, F, E, C, P>(
|
||||
fn scale_framebuffers_with_context_callback<T, F, E, C, P>(
|
||||
source_size: Size<u32>,
|
||||
viewport_size: Size<u32>,
|
||||
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<T, Context = C, Error = E>,
|
||||
C: Copy,
|
||||
F: ScaleFramebuffer<T, Context = C, Error = E>,
|
||||
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(())
|
||||
|
|
Loading…
Reference in a new issue