rt: add viewport extent separate from output texture dimensions

This commit is contained in:
chyyran 2024-08-02 00:25:54 -04:00 committed by Ronny Chan
parent e7e6ed8fb8
commit f0a7970b44
45 changed files with 287 additions and 141 deletions

1
Cargo.lock generated
View file

@ -1543,6 +1543,7 @@ dependencies = [
"glow 0.14.1", "glow 0.14.1",
"halfbrown", "halfbrown",
"num-traits", "num-traits",
"objc2 0.5.2",
"objc2-metal", "objc2-metal",
"rustc-hash 2.0.0", "rustc-hash 2.0.0",
"smartstring", "smartstring",

View file

@ -144,16 +144,18 @@ use librashader::runtime::mtl::FilterChain as FilterChainMetal;
))] ))]
pub type libra_mtl_filter_chain_t = Option<NonNull<FilterChainMetal>>; pub type libra_mtl_filter_chain_t = Option<NonNull<FilterChainMetal>>;
/// Defines the output viewport for a rendered frame. /// Defines the output origin for a rendered frame.
#[repr(C)] #[repr(C)]
pub struct libra_viewport_t { pub struct libra_viewport_t {
/// The x offset in the viewport framebuffer to begin rendering from. /// The x offset in the viewport framebuffer to begin rendering from.
pub x: f32, pub x: f32,
/// The y offset in the viewport framebuffer to begin rendering from. /// The y offset in the viewport framebuffer to begin rendering from.
pub y: f32, pub y: f32,
/// The width of the viewport framebuffer. /// The width extent of the viewport framebuffer to end rendering, relative to
/// the origin specified by x.
pub width: u32, pub width: u32,
/// The height of the viewport framebuffer. /// The height extent of the viewport framebuffer to end rendering, relative to
/// the origin specified by y.
pub height: u32, pub height: u32,
} }

View file

@ -15,7 +15,7 @@ use windows::Win32::Graphics::Direct3D11::{
}; };
use crate::LIBRASHADER_API_VERSION; use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::{FilterChainParameters, Viewport}; use librashader::runtime::{FilterChainParameters, Size, Viewport};
/// Options for Direct3D 11 filter chain creation. /// Options for Direct3D 11 filter chain creation.
#[repr(C)] #[repr(C)]
@ -227,6 +227,10 @@ extern_fn! {
x: viewport.x, x: viewport.x,
y: viewport.y, y: viewport.y,
output: ManuallyDrop::into_inner(out.clone()), output: ManuallyDrop::into_inner(out.clone()),
size: Size {
height: viewport.height,
width: viewport.width
},
mvp, mvp,
}; };

View file

@ -256,7 +256,13 @@ extern_fn! {
let viewport = Viewport { let viewport = Viewport {
x: viewport.x, x: viewport.x,
y: viewport.y, y: viewport.y,
output: unsafe { D3D12OutputView::new_from_raw(out.descriptor, Size::new(out.width, out.height), out.format) }, size: Size {
height: viewport.height,
width: viewport.width
},
output: unsafe {
D3D12OutputView::new_from_raw(out.descriptor,
Size::new(out.width, out.height), out.format) },
mvp, mvp,
}; };

View file

@ -12,7 +12,7 @@ use std::slice;
use windows::Win32::Graphics::Direct3D9::{IDirect3DDevice9, IDirect3DSurface9, IDirect3DTexture9}; use windows::Win32::Graphics::Direct3D9::{IDirect3DDevice9, IDirect3DSurface9, IDirect3DTexture9};
use crate::LIBRASHADER_API_VERSION; use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::{FilterChainParameters, Viewport}; use librashader::runtime::{FilterChainParameters, Size, Viewport};
/// Options for Direct3D 11 filter chain creation. /// Options for Direct3D 11 filter chain creation.
#[repr(C)] #[repr(C)]
@ -147,6 +147,10 @@ extern_fn! {
x: viewport.x, x: viewport.x,
y: viewport.y, y: viewport.y,
output: ManuallyDrop::into_inner(out.clone()), output: ManuallyDrop::into_inner(out.clone()),
size: Size {
height: viewport.height,
width: viewport.width
},
mvp, mvp,
}; };

View file

@ -3,9 +3,13 @@ use crate::ctypes::{
}; };
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError}; use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
use crate::ffi::extern_fn; use crate::ffi::extern_fn;
use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::gl::error::FilterChainError;
use librashader::runtime::gl::{ use librashader::runtime::gl::{
FilterChain, FilterChainOptions, FrameOptions, GLFramebuffer, GLImage, FilterChain, FilterChainOptions, FrameOptions, GLFramebuffer, GLImage,
}; };
use librashader::runtime::FilterChainParameters;
use librashader::runtime::{Size, Viewport};
use std::ffi::CStr; use std::ffi::CStr;
use std::ffi::{c_char, c_void}; use std::ffi::{c_char, c_void};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
@ -13,10 +17,6 @@ use std::num::NonZeroU32;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::slice; use std::slice;
use std::sync::Arc; use std::sync::Arc;
use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::gl::error::FilterChainError;
use librashader::runtime::FilterChainParameters;
use librashader::runtime::{Size, Viewport};
/// A GL function loader that librashader needs to be initialized with. /// A GL function loader that librashader needs to be initialized with.
pub type libra_gl_loader_t = unsafe extern "system" fn(*const c_char) -> *const c_void; pub type libra_gl_loader_t = unsafe extern "system" fn(*const c_char) -> *const c_void;
@ -213,6 +213,10 @@ extern_fn! {
x: viewport.x, x: viewport.x,
y: viewport.y, y: viewport.y,
output: &framebuffer, output: &framebuffer,
size: Size {
height: viewport.height,
width: viewport.width
},
mvp, mvp,
}; };

View file

@ -210,6 +210,10 @@ extern_fn! {
let viewport = Viewport { let viewport = Viewport {
x: viewport.x, x: viewport.x,
y: viewport.y, y: viewport.y,
size: Size {
height: viewport.height,
width: viewport.width
},
output, output,
mvp, mvp,
}; };

View file

@ -289,6 +289,10 @@ extern_fn! {
let viewport = Viewport { let viewport = Viewport {
x: viewport.x, x: viewport.x,
y: viewport.y, y: viewport.y,
size: Size {
height: viewport.height,
width: viewport.width
},
output, output,
mvp, mvp,
}; };

View file

@ -20,7 +20,7 @@ d3d12 = ["windows", "dxgi"]
dxgi = ["windows"] dxgi = ["windows"]
vulkan = ["ash"] vulkan = ["ash"]
wgpu = ["wgpu-types"] wgpu = ["wgpu-types"]
metal = ["objc2-metal"] metal = ["objc2", "objc2-metal"]
[dependencies] [dependencies]
num-traits = "0.2.15" num-traits = "0.2.15"
@ -44,6 +44,13 @@ features = [
"Win32_Graphics_Direct3D12", "Win32_Graphics_Direct3D12",
] ]
[target.'cfg(target_vendor="apple")'.dependencies.objc2]
optional = true
workspace = true
features = ["apple"]
[target.'cfg(target_vendor="apple")'.dependencies.objc2-metal] [target.'cfg(target_vendor="apple")'.dependencies.objc2-metal]
optional = true optional = true
workspace = true workspace = true

View file

@ -1,4 +1,5 @@
use crate::{FilterMode, WrapMode}; use crate::{FilterMode, GetSize, Size, WrapMode};
use windows::core::Interface;
use windows::Win32::Graphics::Direct3D11; use windows::Win32::Graphics::Direct3D11;
impl From<WrapMode> for Direct3D11::D3D11_TEXTURE_ADDRESS_MODE { impl From<WrapMode> for Direct3D11::D3D11_TEXTURE_ADDRESS_MODE {
@ -20,3 +21,39 @@ impl From<FilterMode> for Direct3D11::D3D11_FILTER {
} }
} }
} }
impl GetSize<u32> for Direct3D11::ID3D11RenderTargetView {
type Error = windows::core::Error;
fn size(&self) -> Result<Size<u32>, Self::Error> {
let parent = unsafe { self.GetResource()?.cast::<Direct3D11::ID3D11Texture2D>()? };
let mut desc = Default::default();
unsafe {
parent.GetDesc(&mut desc);
}
Ok(Size {
height: desc.Height,
width: desc.Width,
})
}
}
impl GetSize<u32> for Direct3D11::ID3D11ShaderResourceView {
type Error = windows::core::Error;
fn size(&self) -> Result<Size<u32>, Self::Error> {
let parent = unsafe { self.GetResource()?.cast::<Direct3D11::ID3D11Texture2D>()? };
let mut desc = Default::default();
unsafe {
parent.GetDesc(&mut desc);
}
Ok(Size {
height: desc.Height,
width: desc.Width,
})
}
}

View file

@ -1,4 +1,4 @@
use crate::{FilterMode, WrapMode}; use crate::{FilterMode, GetSize, Size, WrapMode};
use windows::Win32::Graphics::Direct3D12; use windows::Win32::Graphics::Direct3D12;
impl From<WrapMode> for Direct3D12::D3D12_TEXTURE_ADDRESS_MODE { impl From<WrapMode> for Direct3D12::D3D12_TEXTURE_ADDRESS_MODE {
@ -20,3 +20,12 @@ impl From<FilterMode> for Direct3D12::D3D12_FILTER {
} }
} }
} }
impl GetSize<u32> for Direct3D12::ID3D12Resource {
type Error = std::convert::Infallible;
fn size(&self) -> Result<Size<u32>, Self::Error> {
let desc = unsafe { self.GetDesc() };
Ok(Size::new(desc.Width as u32, desc.Height))
}
}

View file

@ -1,4 +1,4 @@
use crate::{FilterMode, ImageFormat, WrapMode}; use crate::{FilterMode, GetSize, ImageFormat, Size, WrapMode};
use windows::Win32::Graphics::Direct3D9; use windows::Win32::Graphics::Direct3D9;
// //
impl From<ImageFormat> for Direct3D9::D3DFORMAT { impl From<ImageFormat> for Direct3D9::D3DFORMAT {
@ -64,6 +64,38 @@ impl From<FilterMode> for Direct3D9::D3DTEXTUREFILTER {
} }
} }
impl GetSize<u32> for Direct3D9::IDirect3DSurface9 {
type Error = windows::core::Error;
fn size(&self) -> Result<Size<u32>, Self::Error> {
let mut desc = Default::default();
unsafe {
self.GetDesc(&mut desc)?;
}
Ok(Size {
height: desc.Height,
width: desc.Width,
})
}
}
impl GetSize<u32> for Direct3D9::IDirect3DTexture9 {
type Error = windows::core::Error;
fn size(&self) -> Result<Size<u32>, Self::Error> {
let mut desc = Default::default();
unsafe {
self.GetLevelDesc(0, &mut desc)?;
}
Ok(Size {
height: desc.Height,
width: desc.Width,
})
}
}
// impl FilterMode { // impl FilterMode {
// /// Get the mipmap filtering mode for the given combination. // /// Get the mipmap filtering mode for the given combination.
// pub fn d3d9_mip(&self, mip: FilterMode) -> Direct3D9::D3DTEXTUREFILTER { // pub fn d3d9_mip(&self, mip: FilterMode) -> Direct3D9::D3DTEXTUREFILTER {

View file

@ -38,7 +38,7 @@ pub mod map;
pub use viewport::Viewport; pub use viewport::Viewport;
use num_traits::AsPrimitive; use num_traits::{AsPrimitive, Num};
use std::convert::Infallible; use std::convert::Infallible;
use std::str::FromStr; use std::str::FromStr;
@ -214,3 +214,22 @@ where
] ]
} }
} }
/// Trait for surface or texture objects that can fetch size.
pub trait GetSize<C: Num> {
type Error;
/// Fetch the size of the object
fn size(&self) -> Result<Size<C>, Self::Error>;
}
impl<T: GetSize<u32>> GetSize<f32> for T {
type Error = T::Error;
fn size(&self) -> Result<Size<f32>, Self::Error> {
let size = <T as GetSize<u32>>::size(self)?;
Ok(Size {
width: size.width as f32,
height: size.height as f32,
})
}
}

View file

@ -1,6 +1,8 @@
use crate::{FilterMode, ImageFormat, Size, WrapMode}; use crate::{FilterMode, GetSize, ImageFormat, Size, WrapMode};
use objc2::runtime::ProtocolObject;
use objc2_metal::{ use objc2_metal::{
MTLPixelFormat, MTLSamplerAddressMode, MTLSamplerMinMagFilter, MTLSamplerMipFilter, MTLViewport, MTLPixelFormat, MTLSamplerAddressMode, MTLSamplerMinMagFilter, MTLSamplerMipFilter, MTLTexture,
MTLViewport,
}; };
impl From<ImageFormat> for MTLPixelFormat { impl From<ImageFormat> for MTLPixelFormat {
@ -92,3 +94,16 @@ impl FilterMode {
} }
} }
} }
impl GetSize<u32> for ProtocolObject<dyn MTLTexture> {
type Error = std::convert::Infallible;
fn size(&self) -> Result<Size<u32>, Self::Error> {
let height = self.height();
let width = self.width();
Ok(Size {
height: height as u32,
width: width as u32,
})
}
}

View file

@ -1,3 +1,5 @@
use crate::Size;
/// The rendering output of a filter chain. /// The rendering output of a filter chain.
pub struct Viewport<'a, T> { pub struct Viewport<'a, T> {
/// The x offset to start rendering from. /// The x offset to start rendering from.
@ -9,4 +11,7 @@ pub struct Viewport<'a, T> {
pub mvp: Option<&'a [f32; 16]>, pub mvp: Option<&'a [f32; 16]>,
/// The output handle to render the final image to. /// The output handle to render the final image to.
pub output: T, pub output: T,
/// The extent of the viewport size starting from the origin defined
/// by x and y.
pub size: Size<u32>,
} }

View file

@ -21,10 +21,11 @@ use crate::graphics_pipeline::D3D11State;
use crate::luts::LutTexture; use crate::luts::LutTexture;
use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11}; use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11};
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::util::{d3d11_compile_bound_shader, GetSize}; use crate::util::d3d11_compile_bound_shader;
use crate::{error, util}; use crate::{error, util};
use librashader_cache::cache_shader_object; use librashader_cache::cache_shader_object;
use librashader_cache::CachedCompilation; use librashader_cache::CachedCompilation;
use librashader_common::GetSize;
use librashader_presets::context::VideoDriver; use librashader_presets::context::VideoDriver;
use librashader_reflect::reflect::cross::SpirvCross; use librashader_reflect::reflect::cross::SpirvCross;
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
@ -490,7 +491,7 @@ impl FilterChainD3D11 {
viewport, viewport,
&original, &original,
&source, &source,
RenderTarget::identity(&target.create_render_target_view()?), RenderTarget::identity(&target.create_render_target_view()?)?,
QuadType::Offscreen, QuadType::Offscreen,
)?; )?;

View file

@ -23,7 +23,7 @@ use windows::Win32::Graphics::Direct3D11::{
use crate::error; use crate::error;
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::util::GetSize; use librashader_common::GetSize;
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess}; use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
pub struct ConstantBufferBinding { pub struct ConstantBufferBinding {

View file

@ -1,8 +1,7 @@
use crate::error; use crate::error;
use crate::error::assume_d3d11_init; use crate::error::assume_d3d11_init;
use librashader_common::Size;
use std::slice; use std::slice;
use windows::core::{Interface, PCSTR}; use windows::core::PCSTR;
use windows::Win32::Graphics::Direct3D::Fxc::{ use windows::Win32::Graphics::Direct3D::Fxc::{
D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_OPTIMIZATION_LEVEL3, D3DCOMPILE_SKIP_OPTIMIZATION, D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_OPTIMIZATION_LEVEL3, D3DCOMPILE_SKIP_OPTIMIZATION,
}; };
@ -179,39 +178,3 @@ pub fn d3d11_create_input_layout(
Ok(input_layout) Ok(input_layout)
} }
} }
pub(crate) trait GetSize {
fn size(&self) -> error::Result<Size<u32>>;
}
impl GetSize for ID3D11RenderTargetView {
fn size(&self) -> error::Result<Size<u32>> {
let parent = unsafe { self.GetResource()?.cast::<ID3D11Texture2D>()? };
let mut desc = Default::default();
unsafe {
parent.GetDesc(&mut desc);
}
Ok(Size {
height: desc.Height,
width: desc.Width,
})
}
}
impl GetSize for ID3D11ShaderResourceView {
fn size(&self) -> error::Result<Size<u32>> {
let parent = unsafe { self.GetResource()?.cast::<ID3D11Texture2D>()? };
let mut desc = Default::default();
unsafe {
parent.GetDesc(&mut desc);
}
Ok(Size {
height: desc.Height,
width: desc.Width,
})
}
}

View file

@ -243,7 +243,7 @@ pub mod d3d11_hello_triangle {
use super::*; use super::*;
use std::path::Path; use std::path::Path;
use librashader_common::{FilterMode, ImageFormat, Size, Viewport, WrapMode}; use librashader_common::{FilterMode, GetSize, ImageFormat, Size, Viewport, WrapMode};
use librashader_runtime::image::Image; use librashader_runtime::image::Image;
use librashader_runtime_d3d11::options::FilterChainOptionsD3D11; use librashader_runtime_d3d11::options::FilterChainOptionsD3D11;
use librashader_runtime_d3d11::FilterChainD3D11; use librashader_runtime_d3d11::FilterChainD3D11;
@ -569,6 +569,8 @@ pub mod d3d11_hello_triangle {
let srv = input_srv.unwrap(); let srv = input_srv.unwrap();
// eprintln!("w: {} h: {}", backbuffer_desc.Width, backbuffer_desc.Height); // eprintln!("w: {} h: {}", backbuffer_desc.Width, backbuffer_desc.Height);
let output = resources.backbuffer_rtv.as_ref().unwrap().clone();
let size = output.size().unwrap();
self.filter self.filter
.frame( .frame(
None, None,
@ -576,8 +578,9 @@ pub mod d3d11_hello_triangle {
&Viewport { &Viewport {
x: 0f32, x: 0f32,
y: 0f32, y: 0f32,
output: resources.backbuffer_rtv.as_ref().unwrap().clone(), output,
mvp: None, mvp: None,
size,
}, },
resources.frame_count, resources.frame_count,
None, None,

View file

@ -26,6 +26,8 @@ pub enum FilterChainError {
HeapError(#[from] D3D12DescriptorHeapError), HeapError(#[from] D3D12DescriptorHeapError),
#[error("allocation error")] #[error("allocation error")]
AllocationError(#[from] gpu_allocator::AllocationError), AllocationError(#[from] gpu_allocator::AllocationError),
#[error("unreachable")]
Infallible(#[from] std::convert::Infallible),
} }
/// Result type for Direct3D 12 filter chains. /// Result type for Direct3D 12 filter chains.

View file

@ -796,7 +796,7 @@ impl FilterChainD3D12 {
)); ));
let view = target.create_render_target_view(&mut self.rtv_heap)?; let view = target.create_render_target_view(&mut self.rtv_heap)?;
let out = RenderTarget::identity(&view); let out = RenderTarget::identity(&view)?;
pass.draw( pass.draw(
cmd, cmd,

View file

@ -1,6 +1,6 @@
use crate::descriptor_heap::{CpuStagingHeap, RenderTargetHeap}; use crate::descriptor_heap::{CpuStagingHeap, RenderTargetHeap};
use d3d12_descriptor_heap::D3D12DescriptorHeapSlot; use d3d12_descriptor_heap::D3D12DescriptorHeapSlot;
use librashader_common::{FilterMode, Size, WrapMode}; use librashader_common::{FilterMode, GetSize, Size, WrapMode};
use windows::Win32::Graphics::Direct3D12::{ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE}; use windows::Win32::Graphics::Direct3D12::{ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
@ -132,3 +132,11 @@ impl AsRef<InputTexture> for InputTexture {
self self
} }
} }
impl GetSize<u32> for D3D12OutputView {
type Error = std::convert::Infallible;
fn size(&self) -> Result<Size<u32>, Self::Error> {
Ok(self.size)
}
}

View file

@ -635,6 +635,10 @@ pub mod d3d12_hello_triangle {
), ),
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
), ),
size: Size::new(
resources.viewport.Width as u32,
resources.viewport.Height as u32,
),
}, },
frame_count, frame_count,
None, None,

View file

@ -32,7 +32,7 @@ use std::collections::VecDeque;
use std::path::Path; use std::path::Path;
use crate::util::GetSize; use librashader_common::GetSize;
use windows::Win32::Graphics::Direct3D9::{IDirect3DDevice9, IDirect3DSurface9, IDirect3DTexture9}; use windows::Win32::Graphics::Direct3D9::{IDirect3DDevice9, IDirect3DSurface9, IDirect3DTexture9};
@ -377,7 +377,7 @@ impl FilterChainD3D9 {
viewport, viewport,
&original, &original,
&source, &source,
RenderTarget::identity(&target_rtv), RenderTarget::identity(&target_rtv)?,
QuadType::Offscreen, QuadType::Offscreen,
)?; )?;

View file

@ -5,6 +5,7 @@ use crate::options::FrameOptionsD3D9;
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::texture::D3D9InputTexture; use crate::texture::D3D9InputTexture;
use librashader_common::map::FastHashMap; use librashader_common::map::FastHashMap;
use librashader_common::GetSize;
use librashader_common::{ImageFormat, Size, Viewport}; use librashader_common::{ImageFormat, Size, Viewport};
use librashader_preprocess::ShaderSource; use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig; use librashader_presets::ShaderPassConfig;
@ -16,7 +17,6 @@ use librashader_runtime::quad::QuadType;
use librashader_runtime::render_target::RenderTarget; use librashader_runtime::render_target::RenderTarget;
use windows::Win32::Foundation::{FALSE, TRUE}; use windows::Win32::Foundation::{FALSE, TRUE};
use crate::util::GetSize;
use windows::Win32::Graphics::Direct3D9::{ use windows::Win32::Graphics::Direct3D9::{
IDirect3DDevice9, IDirect3DPixelShader9, IDirect3DSurface9, IDirect3DVertexShader9, IDirect3DDevice9, IDirect3DPixelShader9, IDirect3DSurface9, IDirect3DVertexShader9,
D3DCLEAR_TARGET, D3DRS_SRGBWRITEENABLE, D3DSAMP_SRGBTEXTURE, D3DVIEWPORT9, D3DCLEAR_TARGET, D3DRS_SRGBWRITEENABLE, D3DSAMP_SRGBTEXTURE, D3DVIEWPORT9,

View file

@ -1,8 +1,7 @@
use crate::error; use crate::error;
use crate::error::{assume_d3d_init, FilterChainError}; use crate::error::{assume_d3d_init, FilterChainError};
use crate::util::GetSize; use librashader_common::{FilterMode, GetSize, ImageFormat, Size, WrapMode};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_presets::Scale2D; use librashader_presets::Scale2D;
use librashader_runtime::binding::TextureInput; use librashader_runtime::binding::TextureInput;
use librashader_runtime::scaling::{ScaleFramebuffer, ViewportSize}; use librashader_runtime::scaling::{ScaleFramebuffer, ViewportSize};

View file

@ -6,11 +6,9 @@ use std::mem::MaybeUninit;
use crate::binding::{ConstantDescriptor, RegisterAssignment, RegisterSet}; use crate::binding::{ConstantDescriptor, RegisterAssignment, RegisterSet};
use crate::d3dx::{ID3DXConstantTable, D3DXCONSTANT_DESC, D3DXREGISTER_SET}; use crate::d3dx::{ID3DXConstantTable, D3DXCONSTANT_DESC, D3DXREGISTER_SET};
use librashader_common::map::FastHashMap; use librashader_common::map::FastHashMap;
use librashader_common::Size;
use windows::core::PCSTR; use windows::core::PCSTR;
use windows::Win32::Graphics::Direct3D::Fxc::{D3DCompile, D3DCOMPILE_AVOID_FLOW_CONTROL}; use windows::Win32::Graphics::Direct3D::Fxc::{D3DCompile, D3DCOMPILE_AVOID_FLOW_CONTROL};
use windows::Win32::Graphics::Direct3D::ID3DBlob; use windows::Win32::Graphics::Direct3D::ID3DBlob;
use windows::Win32::Graphics::Direct3D9::{IDirect3DSurface9, IDirect3DTexture9};
// const fn d3d9_format_fallback_list(format: D3DFORMAT) -> Option<&'static [D3DFORMAT]> { // const fn d3d9_format_fallback_list(format: D3DFORMAT) -> Option<&'static [D3DFORMAT]> {
// match format { // match format {
@ -211,35 +209,3 @@ pub fn d3d_reflect_shader(
Ok(assignments) Ok(assignments)
} }
} }
pub(crate) trait GetSize {
fn size(&self) -> error::Result<Size<u32>>;
}
impl GetSize for IDirect3DSurface9 {
fn size(&self) -> error::Result<Size<u32>> {
let mut desc = Default::default();
unsafe {
self.GetDesc(&mut desc)?;
}
Ok(Size {
height: desc.Height,
width: desc.Width,
})
}
}
impl GetSize for IDirect3DTexture9 {
fn size(&self) -> error::Result<Size<u32>> {
let mut desc = Default::default();
unsafe {
self.GetLevelDesc(0, &mut desc)?;
}
Ok(Size {
height: desc.Height,
width: desc.Width,
})
}
}

View file

@ -194,7 +194,7 @@ pub mod d3d9_hello_triangle {
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use librashader_common::Viewport; use librashader_common::{GetSize, Viewport};
use librashader_runtime::quad::IDENTITY_MVP; use librashader_runtime::quad::IDENTITY_MVP;
use librashader_runtime_d3d9::options::FilterChainOptionsD3D9; use librashader_runtime_d3d9::options::FilterChainOptionsD3D9;
use librashader_runtime_d3d9::FilterChainD3D9; use librashader_runtime_d3d9::FilterChainD3D9;
@ -415,6 +415,7 @@ pub mod d3d9_hello_triangle {
y: 0.0, y: 0.0,
mvp: None, mvp: None,
output: backbuffer.clone(), output: backbuffer.clone(),
size: backbuffer.size().unwrap(),
}, },
0, 0,
None, None,

View file

@ -38,6 +38,8 @@ pub enum FilterChainError {
GlInvalidFramebuffer, GlInvalidFramebuffer,
#[error("opengl error: {0}")] #[error("opengl error: {0}")]
GlError(String), GlError(String),
#[error("unreachable")]
Infallible(#[from] std::convert::Infallible),
} }
/// Result type for OpenGL filter chains. /// Result type for OpenGL filter chains.

View file

@ -371,7 +371,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
viewport, viewport,
&original, &original,
&source, &source,
RenderTarget::identity(target), RenderTarget::identity(target)?,
); );
let target = target.as_texture(pass.config.filter, pass.config.wrap_mode); let target = target.as_texture(pass.config.filter, pass.config.wrap_mode);

View file

@ -1,4 +1,4 @@
use librashader_common::Size; use librashader_common::{GetSize, Size};
/// A handle to an OpenGL texture with format and size information. /// A handle to an OpenGL texture with format and size information.
/// ///
@ -12,3 +12,11 @@ pub struct GLImage {
/// The size of the texture. /// The size of the texture.
pub size: Size<u32>, pub size: Size<u32>,
} }
impl GetSize<u32> for GLImage {
type Error = std::convert::Infallible;
fn size(&self) -> Result<Size<u32>, Self::Error> {
Ok(self.size)
}
}

View file

@ -3,7 +3,7 @@ use crate::framebuffer::GLImage;
use crate::gl::FramebufferInterface; use crate::gl::FramebufferInterface;
use crate::texture::InputTexture; use crate::texture::InputTexture;
use glow::HasContext; use glow::HasContext;
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, GetSize, ImageFormat, Size, WrapMode};
use librashader_presets::Scale2D; use librashader_presets::Scale2D;
use librashader_runtime::scaling::ScaleFramebuffer; use librashader_runtime::scaling::ScaleFramebuffer;
use std::sync::Arc; use std::sync::Arc;
@ -128,3 +128,11 @@ impl<T: FramebufferInterface> ScaleFramebuffer<T> for GLFramebuffer {
) )
} }
} }
impl GetSize<u32> for GLFramebuffer {
type Error = std::convert::Infallible;
fn size(&self) -> std::result::Result<Size<u32>, Self::Error> {
Ok(self.size)
}
}

View file

@ -4,7 +4,7 @@ use std::sync::Arc;
use glfw::{Context, Glfw, Window, WindowEvent}; use glfw::{Context, Glfw, Window, WindowEvent};
use glow::HasContext; use glow::HasContext;
use librashader_common::{Size, Viewport}; use librashader_common::{GetSize, Size, Viewport};
use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage}; use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage};
@ -429,6 +429,7 @@ void main()
y: 0f32, y: 0f32,
output: &output, output: &output,
mvp: None, mvp: None,
size: output.size().unwrap(),
}; };
let rendered = GLImage { let rendered = GLImage {

View file

@ -4,7 +4,7 @@ use std::sync::Arc;
use glfw::{Context, Glfw, Window, WindowEvent}; use glfw::{Context, Glfw, Window, WindowEvent};
use glow::HasContext; use glow::HasContext;
use librashader_common::{Size, Viewport}; use librashader_common::{GetSize, Size, Viewport};
use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage}; use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage};
@ -395,6 +395,7 @@ void main()
y: 0f32, y: 0f32,
output: &output, output: &output,
mvp: None, mvp: None,
size: output.size().unwrap(),
}; };
let rendered = GLImage { let rendered = GLImage {

View file

@ -36,6 +36,8 @@ pub enum FilterChainError {
FailedToCreateTexture, FailedToCreateTexture,
#[error("couldn't create command buffer")] #[error("couldn't create command buffer")]
FailedToCreateCommandBuffer, FailedToCreateCommandBuffer,
#[error("unreachable")]
Infallible(#[from] std::convert::Infallible),
} }
/// Result type for Metal filter chains. /// Result type for Metal filter chains.

View file

@ -445,7 +445,7 @@ impl FilterChainMetal {
source.wrap_mode = pass.config.wrap_mode; source.wrap_mode = pass.config.wrap_mode;
source.mip_filter = pass.config.filter; source.mip_filter = pass.config.filter;
let out = RenderTarget::identity(target.texture.as_ref()); let out = RenderTarget::identity(target.texture.as_ref())?;
pass.draw( pass.draw(
&cmd, &cmd,
index, index,

View file

@ -4,7 +4,6 @@ use librashader_preprocess::PreprocessError;
use librashader_presets::ParsePresetError; use librashader_presets::ParsePresetError;
use librashader_reflect::error::{ShaderCompileError, ShaderReflectError}; use librashader_reflect::error::{ShaderCompileError, ShaderReflectError};
use librashader_runtime::image::ImageError; use librashader_runtime::image::ImageError;
use std::convert::Infallible;
use thiserror::Error; use thiserror::Error;
/// Cumulative error type for Vulkan filter chains. /// Cumulative error type for Vulkan filter chains.
@ -29,12 +28,8 @@ pub enum FilterChainError {
AllocationError(#[from] AllocationError), AllocationError(#[from] AllocationError),
#[error("allocation is already freed")] #[error("allocation is already freed")]
AllocationDoesNotExist, AllocationDoesNotExist,
} #[error("unreachable")]
Infallible(#[from] std::convert::Infallible),
impl From<Infallible> for FilterChainError {
fn from(_value: Infallible) -> Self {
panic!("uninhabited error")
}
} }
/// Result type for Vulkan filter chains. /// Result type for Vulkan filter chains.

View file

@ -683,7 +683,7 @@ impl FilterChainVulkan {
source.mip_filter = pass.config.filter; source.mip_filter = pass.config.filter;
let output_image = OutputImage::new(&self.vulkan.device, target.image.clone())?; let output_image = OutputImage::new(&self.vulkan.device, target.image.clone())?;
let out = RenderTarget::identity(&output_image); let out = RenderTarget::identity(&output_image)?;
let residual_fb = pass.draw( let residual_fb = pass.draw(
cmd, cmd,

View file

@ -1,7 +1,7 @@
use crate::texture::VulkanImage; use crate::texture::VulkanImage;
use crate::{error, util}; use crate::{error, util};
use ash::vk; use ash::vk;
use librashader_common::Size; use librashader_common::{GetSize, Size};
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct OutputImage { pub(crate) struct OutputImage {
@ -79,3 +79,11 @@ impl OutputImage {
} }
} }
} }
impl GetSize<u32> for OutputImage {
type Error = std::convert::Infallible;
fn size(&self) -> Result<Size<u32>, Self::Error> {
Ok(self.size)
}
}

View file

@ -253,6 +253,7 @@ impl VulkanWindow {
format: vulkan.swapchain.format.format, format: vulkan.swapchain.format.format,
}, },
mvp: None, mvp: None,
size: vulkan.swapchain.extent.into(),
}, },
cmd, cmd,
frame, frame,

View file

@ -19,6 +19,8 @@ pub enum FilterChainError {
ShaderReflectError(#[from] ShaderReflectError), ShaderReflectError(#[from] ShaderReflectError),
#[error("lut loading error")] #[error("lut loading error")]
LutLoadError(#[from] ImageError), LutLoadError(#[from] ImageError),
#[error("unreachable")]
Infallible(#[from] std::convert::Infallible),
} }
/// Result type for wgpu filter chains. /// Result type for wgpu filter chains.

View file

@ -452,7 +452,7 @@ impl FilterChainWgpu {
let target = &self.output_framebuffers[index]; let target = &self.output_framebuffers[index];
let output_image = WgpuOutputView::from(target); let output_image = WgpuOutputView::from(target);
let out = RenderTarget::identity(&output_image); let out = RenderTarget::identity(&output_image)?;
pass.draw( pass.draw(
cmd, cmd,

View file

@ -1,6 +1,7 @@
use crate::error::FilterChainError; use crate::error::FilterChainError;
use crate::mipmap::MipmapGen; use crate::mipmap::MipmapGen;
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use crate::WgpuOutputView;
use librashader_common::{FilterMode, GetSize, ImageFormat, Size, WrapMode};
use librashader_presets::Scale2D; use librashader_presets::Scale2D;
use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize}; use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize};
use std::sync::Arc; use std::sync::Arc;
@ -17,7 +18,6 @@ pub struct OwnedImage {
#[derive(Clone)] #[derive(Clone)]
pub struct InputImage { pub struct InputImage {
/// A handle to the `VkImage`.
pub image: Arc<wgpu::Texture>, pub image: Arc<wgpu::Texture>,
pub view: Arc<wgpu::TextureView>, pub view: Arc<wgpu::TextureView>,
pub wrap_mode: WrapMode, pub wrap_mode: WrapMode,
@ -167,3 +167,11 @@ impl ScaleFramebuffer for OwnedImage {
)) ))
} }
} }
impl GetSize<u32> for WgpuOutputView<'_> {
type Error = std::convert::Infallible;
fn size(&self) -> Result<Size<u32>, Self::Error> {
Ok(self.size)
}
}

View file

@ -127,10 +127,8 @@ impl<'a> State<'a> {
let preset = let preset =
ShaderPreset::try_parse("../test/shaders_slang/crt/crt-royale.slangp").unwrap(); ShaderPreset::try_parse("../test/shaders_slang/crt/crt-royale.slangp").unwrap();
// let preset = ShaderPreset::try_parse( // let preset =
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", // ShaderPreset::try_parse("../test/shaders_slang/crt/crt-royale.slangp").unwrap();
// )
// .unwrap();
let chain = FilterChainWgpu::load_from_preset( let chain = FilterChainWgpu::load_from_preset(
preset, preset,
@ -300,6 +298,7 @@ impl<'a> State<'a> {
filter_output.size().into(), filter_output.size().into(),
filter_output.format(), filter_output.format(),
), ),
size: filter_output.size().into(),
}, },
&mut encoder, &mut encoder,
self.frame_count, self.frame_count,

View file

@ -1,5 +1,5 @@
use crate::quad::{DEFAULT_MVP, IDENTITY_MVP}; use crate::quad::{DEFAULT_MVP, IDENTITY_MVP};
use librashader_common::Viewport; use librashader_common::{GetSize, Size, Viewport};
use num_traits::{zero, AsPrimitive, Num}; use num_traits::{zero, AsPrimitive, Num};
use std::borrow::Borrow; use std::borrow::Borrow;
@ -17,21 +17,30 @@ where
pub mvp: &'a [f32; 16], pub mvp: &'a [f32; 16],
/// The output surface for the pass. /// The output surface for the pass.
pub output: &'a T, pub output: &'a T,
/// The extent of the render target, starting from the origin defined
/// by x and y.
pub size: Size<u32>,
} }
impl<'a, T, C: Num> RenderTarget<'a, T, C> { impl<'a, T: GetSize<u32>, C: Num> RenderTarget<'a, T, C> {
/// Create a new render target. /// Create a new render target.
pub fn new(output: &'a T, mvp: &'a [f32; 16], x: C, y: C) -> Self { pub fn new(output: &'a T, mvp: &'a [f32; 16], x: C, y: C) -> Result<Self, T::Error> {
RenderTarget { output, mvp, x, y } Ok(RenderTarget {
output,
mvp,
x,
y,
size: output.size()?,
})
} }
/// Create a render target with the identity MVP. /// Create a render target with the identity MVP.
pub fn identity(output: &'a T) -> Self { pub fn identity(output: &'a T) -> Result<Self, T::Error> {
Self::offscreen(output, IDENTITY_MVP) Self::offscreen(output, IDENTITY_MVP)
} }
/// Create an offscreen render target with the given MVP. /// Create an offscreen render target with the given MVP.
pub fn offscreen(output: &'a T, mvp: &'a [f32; 16]) -> Self { pub fn offscreen(output: &'a T, mvp: &'a [f32; 16]) -> Result<Self, T::Error> {
Self::new(output, mvp, zero(), zero()) Self::new(output, mvp, zero(), zero())
} }
} }
@ -42,21 +51,23 @@ where
{ {
/// Create a viewport render target. /// Create a viewport render target.
pub fn viewport(viewport: &'a Viewport<'a, impl Borrow<T>>) -> Self { pub fn viewport(viewport: &'a Viewport<'a, impl Borrow<T>>) -> Self {
Self::new( RenderTarget {
viewport.output.borrow(), output: viewport.output.borrow(),
viewport.mvp.unwrap_or(DEFAULT_MVP), mvp: viewport.mvp.unwrap_or(DEFAULT_MVP),
viewport.x.as_(), x: viewport.x.as_(),
viewport.y.as_(), y: viewport.y.as_(),
) size: viewport.size,
}
} }
/// Create a viewport render target with the given output. /// Create a viewport render target with the given output.
pub fn viewport_with_output<S>(output: &'a T, viewport: &'a Viewport<'a, S>) -> Self { pub fn viewport_with_output<S>(output: &'a T, viewport: &'a Viewport<'a, S>) -> Self {
Self::new( RenderTarget {
output, output,
viewport.mvp.unwrap_or(DEFAULT_MVP), mvp: viewport.mvp.unwrap_or(DEFAULT_MVP),
viewport.x.as_(), x: viewport.x.as_(),
viewport.y.as_(), y: viewport.y.as_(),
) size: viewport.size,
}
} }
} }