diff --git a/Cargo.lock b/Cargo.lock index 9143397..70d1bdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1543,6 +1543,7 @@ dependencies = [ "glow 0.14.1", "halfbrown", "num-traits", + "objc2 0.5.2", "objc2-metal", "rustc-hash 2.0.0", "smartstring", diff --git a/librashader-capi/src/ctypes.rs b/librashader-capi/src/ctypes.rs index ced4d1c..0a250d7 100644 --- a/librashader-capi/src/ctypes.rs +++ b/librashader-capi/src/ctypes.rs @@ -144,16 +144,18 @@ use librashader::runtime::mtl::FilterChain as FilterChainMetal; ))] pub type libra_mtl_filter_chain_t = Option>; -/// Defines the output viewport for a rendered frame. +/// Defines the output origin for a rendered frame. #[repr(C)] pub struct libra_viewport_t { /// The x offset in the viewport framebuffer to begin rendering from. pub x: f32, /// The y offset in the viewport framebuffer to begin rendering from. 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, - /// 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, } diff --git a/librashader-capi/src/runtime/d3d11/filter_chain.rs b/librashader-capi/src/runtime/d3d11/filter_chain.rs index b8879ff..9b92ace 100644 --- a/librashader-capi/src/runtime/d3d11/filter_chain.rs +++ b/librashader-capi/src/runtime/d3d11/filter_chain.rs @@ -15,7 +15,7 @@ use windows::Win32::Graphics::Direct3D11::{ }; use crate::LIBRASHADER_API_VERSION; -use librashader::runtime::{FilterChainParameters, Viewport}; +use librashader::runtime::{FilterChainParameters, Size, Viewport}; /// Options for Direct3D 11 filter chain creation. #[repr(C)] @@ -227,6 +227,10 @@ extern_fn! { x: viewport.x, y: viewport.y, output: ManuallyDrop::into_inner(out.clone()), + size: Size { + height: viewport.height, + width: viewport.width + }, mvp, }; diff --git a/librashader-capi/src/runtime/d3d12/filter_chain.rs b/librashader-capi/src/runtime/d3d12/filter_chain.rs index e1a81cb..bfe0bb1 100644 --- a/librashader-capi/src/runtime/d3d12/filter_chain.rs +++ b/librashader-capi/src/runtime/d3d12/filter_chain.rs @@ -256,7 +256,13 @@ extern_fn! { let viewport = Viewport { x: viewport.x, 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, }; diff --git a/librashader-capi/src/runtime/d3d9/filter_chain.rs b/librashader-capi/src/runtime/d3d9/filter_chain.rs index 5245d28..e3d7ff2 100644 --- a/librashader-capi/src/runtime/d3d9/filter_chain.rs +++ b/librashader-capi/src/runtime/d3d9/filter_chain.rs @@ -12,7 +12,7 @@ use std::slice; use windows::Win32::Graphics::Direct3D9::{IDirect3DDevice9, IDirect3DSurface9, IDirect3DTexture9}; use crate::LIBRASHADER_API_VERSION; -use librashader::runtime::{FilterChainParameters, Viewport}; +use librashader::runtime::{FilterChainParameters, Size, Viewport}; /// Options for Direct3D 11 filter chain creation. #[repr(C)] @@ -147,6 +147,10 @@ extern_fn! { x: viewport.x, y: viewport.y, output: ManuallyDrop::into_inner(out.clone()), + size: Size { + height: viewport.height, + width: viewport.width + }, mvp, }; diff --git a/librashader-capi/src/runtime/gl/filter_chain.rs b/librashader-capi/src/runtime/gl/filter_chain.rs index 6f1cfec..e26369b 100644 --- a/librashader-capi/src/runtime/gl/filter_chain.rs +++ b/librashader-capi/src/runtime/gl/filter_chain.rs @@ -3,9 +3,13 @@ use crate::ctypes::{ }; use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError}; use crate::ffi::extern_fn; +use crate::LIBRASHADER_API_VERSION; +use librashader::runtime::gl::error::FilterChainError; use librashader::runtime::gl::{ FilterChain, FilterChainOptions, FrameOptions, GLFramebuffer, GLImage, }; +use librashader::runtime::FilterChainParameters; +use librashader::runtime::{Size, Viewport}; use std::ffi::CStr; use std::ffi::{c_char, c_void}; use std::mem::MaybeUninit; @@ -13,10 +17,6 @@ use std::num::NonZeroU32; use std::ptr::NonNull; use std::slice; 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. 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, y: viewport.y, output: &framebuffer, + size: Size { + height: viewport.height, + width: viewport.width + }, mvp, }; diff --git a/librashader-capi/src/runtime/mtl/filter_chain.rs b/librashader-capi/src/runtime/mtl/filter_chain.rs index fa45485..a8ac8e9 100644 --- a/librashader-capi/src/runtime/mtl/filter_chain.rs +++ b/librashader-capi/src/runtime/mtl/filter_chain.rs @@ -210,6 +210,10 @@ extern_fn! { let viewport = Viewport { x: viewport.x, y: viewport.y, + size: Size { + height: viewport.height, + width: viewport.width + }, output, mvp, }; diff --git a/librashader-capi/src/runtime/vk/filter_chain.rs b/librashader-capi/src/runtime/vk/filter_chain.rs index 9dbf1a9..853ef53 100644 --- a/librashader-capi/src/runtime/vk/filter_chain.rs +++ b/librashader-capi/src/runtime/vk/filter_chain.rs @@ -289,6 +289,10 @@ extern_fn! { let viewport = Viewport { x: viewport.x, y: viewport.y, + size: Size { + height: viewport.height, + width: viewport.width + }, output, mvp, }; diff --git a/librashader-common/Cargo.toml b/librashader-common/Cargo.toml index 55db363..0af2428 100644 --- a/librashader-common/Cargo.toml +++ b/librashader-common/Cargo.toml @@ -20,7 +20,7 @@ d3d12 = ["windows", "dxgi"] dxgi = ["windows"] vulkan = ["ash"] wgpu = ["wgpu-types"] -metal = ["objc2-metal"] +metal = ["objc2", "objc2-metal"] [dependencies] num-traits = "0.2.15" @@ -44,6 +44,13 @@ features = [ "Win32_Graphics_Direct3D12", ] + +[target.'cfg(target_vendor="apple")'.dependencies.objc2] +optional = true +workspace = true +features = ["apple"] + + [target.'cfg(target_vendor="apple")'.dependencies.objc2-metal] optional = true workspace = true diff --git a/librashader-common/src/d3d11.rs b/librashader-common/src/d3d11.rs index 9516205..cb7015d 100644 --- a/librashader-common/src/d3d11.rs +++ b/librashader-common/src/d3d11.rs @@ -1,4 +1,5 @@ -use crate::{FilterMode, WrapMode}; +use crate::{FilterMode, GetSize, Size, WrapMode}; +use windows::core::Interface; use windows::Win32::Graphics::Direct3D11; impl From for Direct3D11::D3D11_TEXTURE_ADDRESS_MODE { @@ -20,3 +21,39 @@ impl From for Direct3D11::D3D11_FILTER { } } } + +impl GetSize for Direct3D11::ID3D11RenderTargetView { + type Error = windows::core::Error; + + fn size(&self) -> Result, Self::Error> { + let parent = unsafe { self.GetResource()?.cast::()? }; + + let mut desc = Default::default(); + unsafe { + parent.GetDesc(&mut desc); + } + + Ok(Size { + height: desc.Height, + width: desc.Width, + }) + } +} + +impl GetSize for Direct3D11::ID3D11ShaderResourceView { + type Error = windows::core::Error; + + fn size(&self) -> Result, Self::Error> { + let parent = unsafe { self.GetResource()?.cast::()? }; + + let mut desc = Default::default(); + unsafe { + parent.GetDesc(&mut desc); + } + + Ok(Size { + height: desc.Height, + width: desc.Width, + }) + } +} diff --git a/librashader-common/src/d3d12.rs b/librashader-common/src/d3d12.rs index 744ff7a..bcd96de 100644 --- a/librashader-common/src/d3d12.rs +++ b/librashader-common/src/d3d12.rs @@ -1,4 +1,4 @@ -use crate::{FilterMode, WrapMode}; +use crate::{FilterMode, GetSize, Size, WrapMode}; use windows::Win32::Graphics::Direct3D12; impl From for Direct3D12::D3D12_TEXTURE_ADDRESS_MODE { @@ -20,3 +20,12 @@ impl From for Direct3D12::D3D12_FILTER { } } } + +impl GetSize for Direct3D12::ID3D12Resource { + type Error = std::convert::Infallible; + fn size(&self) -> Result, Self::Error> { + let desc = unsafe { self.GetDesc() }; + + Ok(Size::new(desc.Width as u32, desc.Height)) + } +} diff --git a/librashader-common/src/d3d9.rs b/librashader-common/src/d3d9.rs index 1be70f9..f123335 100644 --- a/librashader-common/src/d3d9.rs +++ b/librashader-common/src/d3d9.rs @@ -1,4 +1,4 @@ -use crate::{FilterMode, ImageFormat, WrapMode}; +use crate::{FilterMode, GetSize, ImageFormat, Size, WrapMode}; use windows::Win32::Graphics::Direct3D9; // impl From for Direct3D9::D3DFORMAT { @@ -64,6 +64,38 @@ impl From for Direct3D9::D3DTEXTUREFILTER { } } +impl GetSize for Direct3D9::IDirect3DSurface9 { + type Error = windows::core::Error; + + fn size(&self) -> Result, Self::Error> { + let mut desc = Default::default(); + unsafe { + self.GetDesc(&mut desc)?; + } + + Ok(Size { + height: desc.Height, + width: desc.Width, + }) + } +} + +impl GetSize for Direct3D9::IDirect3DTexture9 { + type Error = windows::core::Error; + + fn size(&self) -> Result, Self::Error> { + let mut desc = Default::default(); + unsafe { + self.GetLevelDesc(0, &mut desc)?; + } + + Ok(Size { + height: desc.Height, + width: desc.Width, + }) + } +} + // impl FilterMode { // /// Get the mipmap filtering mode for the given combination. // pub fn d3d9_mip(&self, mip: FilterMode) -> Direct3D9::D3DTEXTUREFILTER { diff --git a/librashader-common/src/lib.rs b/librashader-common/src/lib.rs index b78abef..1880559 100644 --- a/librashader-common/src/lib.rs +++ b/librashader-common/src/lib.rs @@ -38,7 +38,7 @@ pub mod map; pub use viewport::Viewport; -use num_traits::AsPrimitive; +use num_traits::{AsPrimitive, Num}; use std::convert::Infallible; use std::str::FromStr; @@ -214,3 +214,22 @@ where ] } } + +/// Trait for surface or texture objects that can fetch size. +pub trait GetSize { + type Error; + /// Fetch the size of the object + fn size(&self) -> Result, Self::Error>; +} + +impl> GetSize for T { + type Error = T::Error; + + fn size(&self) -> Result, Self::Error> { + let size = >::size(self)?; + Ok(Size { + width: size.width as f32, + height: size.height as f32, + }) + } +} diff --git a/librashader-common/src/metal.rs b/librashader-common/src/metal.rs index 3a791b3..34d9c25 100644 --- a/librashader-common/src/metal.rs +++ b/librashader-common/src/metal.rs @@ -1,6 +1,8 @@ -use crate::{FilterMode, ImageFormat, Size, WrapMode}; +use crate::{FilterMode, GetSize, ImageFormat, Size, WrapMode}; +use objc2::runtime::ProtocolObject; use objc2_metal::{ - MTLPixelFormat, MTLSamplerAddressMode, MTLSamplerMinMagFilter, MTLSamplerMipFilter, MTLViewport, + MTLPixelFormat, MTLSamplerAddressMode, MTLSamplerMinMagFilter, MTLSamplerMipFilter, MTLTexture, + MTLViewport, }; impl From for MTLPixelFormat { @@ -92,3 +94,16 @@ impl FilterMode { } } } + +impl GetSize for ProtocolObject { + type Error = std::convert::Infallible; + + fn size(&self) -> Result, Self::Error> { + let height = self.height(); + let width = self.width(); + Ok(Size { + height: height as u32, + width: width as u32, + }) + } +} diff --git a/librashader-common/src/viewport.rs b/librashader-common/src/viewport.rs index 8a6a53e..8456cfe 100644 --- a/librashader-common/src/viewport.rs +++ b/librashader-common/src/viewport.rs @@ -1,3 +1,5 @@ +use crate::Size; + /// The rendering output of a filter chain. pub struct Viewport<'a, T> { /// The x offset to start rendering from. @@ -9,4 +11,7 @@ pub struct Viewport<'a, T> { pub mvp: Option<&'a [f32; 16]>, /// The output handle to render the final image to. pub output: T, + /// The extent of the viewport size starting from the origin defined + /// by x and y. + pub size: Size, } diff --git a/librashader-runtime-d3d11/src/filter_chain.rs b/librashader-runtime-d3d11/src/filter_chain.rs index 67ed9d8..acd281b 100644 --- a/librashader-runtime-d3d11/src/filter_chain.rs +++ b/librashader-runtime-d3d11/src/filter_chain.rs @@ -21,10 +21,11 @@ use crate::graphics_pipeline::D3D11State; use crate::luts::LutTexture; use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11}; use crate::samplers::SamplerSet; -use crate::util::{d3d11_compile_bound_shader, GetSize}; +use crate::util::d3d11_compile_bound_shader; use crate::{error, util}; use librashader_cache::cache_shader_object; use librashader_cache::CachedCompilation; +use librashader_common::GetSize; use librashader_presets::context::VideoDriver; use librashader_reflect::reflect::cross::SpirvCross; use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; @@ -490,7 +491,7 @@ impl FilterChainD3D11 { viewport, &original, &source, - RenderTarget::identity(&target.create_render_target_view()?), + RenderTarget::identity(&target.create_render_target_view()?)?, QuadType::Offscreen, )?; diff --git a/librashader-runtime-d3d11/src/filter_pass.rs b/librashader-runtime-d3d11/src/filter_pass.rs index 0c2451e..a17b94b 100644 --- a/librashader-runtime-d3d11/src/filter_pass.rs +++ b/librashader-runtime-d3d11/src/filter_pass.rs @@ -23,7 +23,7 @@ use windows::Win32::Graphics::Direct3D11::{ use crate::error; use crate::samplers::SamplerSet; -use crate::util::GetSize; +use librashader_common::GetSize; use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess}; pub struct ConstantBufferBinding { diff --git a/librashader-runtime-d3d11/src/util.rs b/librashader-runtime-d3d11/src/util.rs index 6ec51a6..d95cd68 100644 --- a/librashader-runtime-d3d11/src/util.rs +++ b/librashader-runtime-d3d11/src/util.rs @@ -1,8 +1,7 @@ use crate::error; use crate::error::assume_d3d11_init; -use librashader_common::Size; use std::slice; -use windows::core::{Interface, PCSTR}; +use windows::core::PCSTR; use windows::Win32::Graphics::Direct3D::Fxc::{ D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_OPTIMIZATION_LEVEL3, D3DCOMPILE_SKIP_OPTIMIZATION, }; @@ -179,39 +178,3 @@ pub fn d3d11_create_input_layout( Ok(input_layout) } } - -pub(crate) trait GetSize { - fn size(&self) -> error::Result>; -} - -impl GetSize for ID3D11RenderTargetView { - fn size(&self) -> error::Result> { - let parent = unsafe { self.GetResource()?.cast::()? }; - - 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> { - let parent = unsafe { self.GetResource()?.cast::()? }; - - let mut desc = Default::default(); - unsafe { - parent.GetDesc(&mut desc); - } - - Ok(Size { - height: desc.Height, - width: desc.Width, - }) - } -} diff --git a/librashader-runtime-d3d11/tests/hello_triangle/mod.rs b/librashader-runtime-d3d11/tests/hello_triangle/mod.rs index de9a08e..f713d26 100644 --- a/librashader-runtime-d3d11/tests/hello_triangle/mod.rs +++ b/librashader-runtime-d3d11/tests/hello_triangle/mod.rs @@ -243,7 +243,7 @@ pub mod d3d11_hello_triangle { use super::*; 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_d3d11::options::FilterChainOptionsD3D11; use librashader_runtime_d3d11::FilterChainD3D11; @@ -569,6 +569,8 @@ pub mod d3d11_hello_triangle { let srv = input_srv.unwrap(); // 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 .frame( None, @@ -576,8 +578,9 @@ pub mod d3d11_hello_triangle { &Viewport { x: 0f32, y: 0f32, - output: resources.backbuffer_rtv.as_ref().unwrap().clone(), + output, mvp: None, + size, }, resources.frame_count, None, diff --git a/librashader-runtime-d3d12/src/error.rs b/librashader-runtime-d3d12/src/error.rs index fec9416..7139d07 100644 --- a/librashader-runtime-d3d12/src/error.rs +++ b/librashader-runtime-d3d12/src/error.rs @@ -26,6 +26,8 @@ pub enum FilterChainError { HeapError(#[from] D3D12DescriptorHeapError), #[error("allocation error")] AllocationError(#[from] gpu_allocator::AllocationError), + #[error("unreachable")] + Infallible(#[from] std::convert::Infallible), } /// 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 06eb721..d2801f1 100644 --- a/librashader-runtime-d3d12/src/filter_chain.rs +++ b/librashader-runtime-d3d12/src/filter_chain.rs @@ -796,7 +796,7 @@ impl FilterChainD3D12 { )); let view = target.create_render_target_view(&mut self.rtv_heap)?; - let out = RenderTarget::identity(&view); + let out = RenderTarget::identity(&view)?; pass.draw( cmd, diff --git a/librashader-runtime-d3d12/src/texture.rs b/librashader-runtime-d3d12/src/texture.rs index 803d14a..ab3003b 100644 --- a/librashader-runtime-d3d12/src/texture.rs +++ b/librashader-runtime-d3d12/src/texture.rs @@ -1,6 +1,6 @@ use crate::descriptor_heap::{CpuStagingHeap, RenderTargetHeap}; 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::Dxgi::Common::DXGI_FORMAT; @@ -132,3 +132,11 @@ impl AsRef for InputTexture { self } } + +impl GetSize for D3D12OutputView { + type Error = std::convert::Infallible; + + fn size(&self) -> Result, Self::Error> { + Ok(self.size) + } +} diff --git a/librashader-runtime-d3d12/tests/hello_triangle/mod.rs b/librashader-runtime-d3d12/tests/hello_triangle/mod.rs index ba76a49..74d5fa8 100644 --- a/librashader-runtime-d3d12/tests/hello_triangle/mod.rs +++ b/librashader-runtime-d3d12/tests/hello_triangle/mod.rs @@ -635,6 +635,10 @@ pub mod d3d12_hello_triangle { ), DXGI_FORMAT_R8G8B8A8_UNORM, ), + size: Size::new( + resources.viewport.Width as u32, + resources.viewport.Height as u32, + ), }, frame_count, None, diff --git a/librashader-runtime-d3d9/src/filter_chain.rs b/librashader-runtime-d3d9/src/filter_chain.rs index b713b72..ffdb010 100644 --- a/librashader-runtime-d3d9/src/filter_chain.rs +++ b/librashader-runtime-d3d9/src/filter_chain.rs @@ -32,7 +32,7 @@ use std::collections::VecDeque; use std::path::Path; -use crate::util::GetSize; +use librashader_common::GetSize; use windows::Win32::Graphics::Direct3D9::{IDirect3DDevice9, IDirect3DSurface9, IDirect3DTexture9}; @@ -377,7 +377,7 @@ impl FilterChainD3D9 { viewport, &original, &source, - RenderTarget::identity(&target_rtv), + RenderTarget::identity(&target_rtv)?, QuadType::Offscreen, )?; diff --git a/librashader-runtime-d3d9/src/filter_pass.rs b/librashader-runtime-d3d9/src/filter_pass.rs index 594401f..c127248 100644 --- a/librashader-runtime-d3d9/src/filter_pass.rs +++ b/librashader-runtime-d3d9/src/filter_pass.rs @@ -5,6 +5,7 @@ use crate::options::FrameOptionsD3D9; use crate::samplers::SamplerSet; use crate::texture::D3D9InputTexture; use librashader_common::map::FastHashMap; +use librashader_common::GetSize; use librashader_common::{ImageFormat, Size, Viewport}; use librashader_preprocess::ShaderSource; use librashader_presets::ShaderPassConfig; @@ -16,7 +17,6 @@ use librashader_runtime::quad::QuadType; use librashader_runtime::render_target::RenderTarget; use windows::Win32::Foundation::{FALSE, TRUE}; -use crate::util::GetSize; use windows::Win32::Graphics::Direct3D9::{ IDirect3DDevice9, IDirect3DPixelShader9, IDirect3DSurface9, IDirect3DVertexShader9, D3DCLEAR_TARGET, D3DRS_SRGBWRITEENABLE, D3DSAMP_SRGBTEXTURE, D3DVIEWPORT9, diff --git a/librashader-runtime-d3d9/src/texture.rs b/librashader-runtime-d3d9/src/texture.rs index bbd2fad..b9b29da 100644 --- a/librashader-runtime-d3d9/src/texture.rs +++ b/librashader-runtime-d3d9/src/texture.rs @@ -1,8 +1,7 @@ use crate::error; use crate::error::{assume_d3d_init, FilterChainError}; -use crate::util::GetSize; -use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; +use librashader_common::{FilterMode, GetSize, ImageFormat, Size, WrapMode}; use librashader_presets::Scale2D; use librashader_runtime::binding::TextureInput; use librashader_runtime::scaling::{ScaleFramebuffer, ViewportSize}; diff --git a/librashader-runtime-d3d9/src/util.rs b/librashader-runtime-d3d9/src/util.rs index 6e52438..9a711f4 100644 --- a/librashader-runtime-d3d9/src/util.rs +++ b/librashader-runtime-d3d9/src/util.rs @@ -6,11 +6,9 @@ use std::mem::MaybeUninit; use crate::binding::{ConstantDescriptor, RegisterAssignment, RegisterSet}; use crate::d3dx::{ID3DXConstantTable, D3DXCONSTANT_DESC, D3DXREGISTER_SET}; use librashader_common::map::FastHashMap; -use librashader_common::Size; use windows::core::PCSTR; use windows::Win32::Graphics::Direct3D::Fxc::{D3DCompile, D3DCOMPILE_AVOID_FLOW_CONTROL}; use windows::Win32::Graphics::Direct3D::ID3DBlob; -use windows::Win32::Graphics::Direct3D9::{IDirect3DSurface9, IDirect3DTexture9}; // const fn d3d9_format_fallback_list(format: D3DFORMAT) -> Option<&'static [D3DFORMAT]> { // match format { @@ -211,35 +209,3 @@ pub fn d3d_reflect_shader( Ok(assignments) } } - -pub(crate) trait GetSize { - fn size(&self) -> error::Result>; -} - -impl GetSize for IDirect3DSurface9 { - fn size(&self) -> error::Result> { - 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> { - let mut desc = Default::default(); - unsafe { - self.GetLevelDesc(0, &mut desc)?; - } - - Ok(Size { - height: desc.Height, - width: desc.Width, - }) - } -} diff --git a/librashader-runtime-d3d9/tests/hello_triangle/mod.rs b/librashader-runtime-d3d9/tests/hello_triangle/mod.rs index 2878a77..112d23a 100644 --- a/librashader-runtime-d3d9/tests/hello_triangle/mod.rs +++ b/librashader-runtime-d3d9/tests/hello_triangle/mod.rs @@ -194,7 +194,7 @@ pub mod d3d9_hello_triangle { use std::path::{Path, PathBuf}; - use librashader_common::Viewport; + use librashader_common::{GetSize, Viewport}; use librashader_runtime::quad::IDENTITY_MVP; use librashader_runtime_d3d9::options::FilterChainOptionsD3D9; use librashader_runtime_d3d9::FilterChainD3D9; @@ -415,6 +415,7 @@ pub mod d3d9_hello_triangle { y: 0.0, mvp: None, output: backbuffer.clone(), + size: backbuffer.size().unwrap(), }, 0, None, diff --git a/librashader-runtime-gl/src/error.rs b/librashader-runtime-gl/src/error.rs index be4ed8d..49b3ce1 100644 --- a/librashader-runtime-gl/src/error.rs +++ b/librashader-runtime-gl/src/error.rs @@ -38,6 +38,8 @@ pub enum FilterChainError { GlInvalidFramebuffer, #[error("opengl error: {0}")] GlError(String), + #[error("unreachable")] + Infallible(#[from] std::convert::Infallible), } /// Result type for OpenGL filter chains. diff --git a/librashader-runtime-gl/src/filter_chain/chain.rs b/librashader-runtime-gl/src/filter_chain/chain.rs index c107235..d750ac4 100644 --- a/librashader-runtime-gl/src/filter_chain/chain.rs +++ b/librashader-runtime-gl/src/filter_chain/chain.rs @@ -371,7 +371,7 @@ impl FilterChainImpl { viewport, &original, &source, - RenderTarget::identity(target), + RenderTarget::identity(target)?, ); let target = target.as_texture(pass.config.filter, pass.config.wrap_mode); diff --git a/librashader-runtime-gl/src/framebuffer.rs b/librashader-runtime-gl/src/framebuffer.rs index dd737a6..50ef287 100644 --- a/librashader-runtime-gl/src/framebuffer.rs +++ b/librashader-runtime-gl/src/framebuffer.rs @@ -1,4 +1,4 @@ -use librashader_common::Size; +use librashader_common::{GetSize, Size}; /// A handle to an OpenGL texture with format and size information. /// @@ -12,3 +12,11 @@ pub struct GLImage { /// The size of the texture. pub size: Size, } + +impl GetSize for GLImage { + type Error = std::convert::Infallible; + + fn size(&self) -> Result, Self::Error> { + Ok(self.size) + } +} diff --git a/librashader-runtime-gl/src/gl/framebuffer.rs b/librashader-runtime-gl/src/gl/framebuffer.rs index 2bde540..1fd9adf 100644 --- a/librashader-runtime-gl/src/gl/framebuffer.rs +++ b/librashader-runtime-gl/src/gl/framebuffer.rs @@ -3,7 +3,7 @@ use crate::framebuffer::GLImage; use crate::gl::FramebufferInterface; use crate::texture::InputTexture; use glow::HasContext; -use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; +use librashader_common::{FilterMode, GetSize, ImageFormat, Size, WrapMode}; use librashader_presets::Scale2D; use librashader_runtime::scaling::ScaleFramebuffer; use std::sync::Arc; @@ -128,3 +128,11 @@ impl ScaleFramebuffer for GLFramebuffer { ) } } + +impl GetSize for GLFramebuffer { + type Error = std::convert::Infallible; + + fn size(&self) -> std::result::Result, Self::Error> { + Ok(self.size) + } +} diff --git a/librashader-runtime-gl/tests/hello_triangle/gl3.rs b/librashader-runtime-gl/tests/hello_triangle/gl3.rs index 440dab1..8e990f0 100644 --- a/librashader-runtime-gl/tests/hello_triangle/gl3.rs +++ b/librashader-runtime-gl/tests/hello_triangle/gl3.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use glfw::{Context, Glfw, Window, WindowEvent}; use glow::HasContext; -use librashader_common::{Size, Viewport}; +use librashader_common::{GetSize, Size, Viewport}; use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage}; @@ -429,6 +429,7 @@ void main() y: 0f32, output: &output, mvp: None, + size: output.size().unwrap(), }; let rendered = GLImage { diff --git a/librashader-runtime-gl/tests/hello_triangle/gl46.rs b/librashader-runtime-gl/tests/hello_triangle/gl46.rs index cd77e05..b4fe040 100644 --- a/librashader-runtime-gl/tests/hello_triangle/gl46.rs +++ b/librashader-runtime-gl/tests/hello_triangle/gl46.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use glfw::{Context, Glfw, Window, WindowEvent}; use glow::HasContext; -use librashader_common::{Size, Viewport}; +use librashader_common::{GetSize, Size, Viewport}; use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage}; @@ -395,6 +395,7 @@ void main() y: 0f32, output: &output, mvp: None, + size: output.size().unwrap(), }; let rendered = GLImage { diff --git a/librashader-runtime-mtl/src/error.rs b/librashader-runtime-mtl/src/error.rs index 2bf1e92..f611c6a 100644 --- a/librashader-runtime-mtl/src/error.rs +++ b/librashader-runtime-mtl/src/error.rs @@ -36,6 +36,8 @@ pub enum FilterChainError { FailedToCreateTexture, #[error("couldn't create command buffer")] FailedToCreateCommandBuffer, + #[error("unreachable")] + Infallible(#[from] std::convert::Infallible), } /// Result type for Metal filter chains. diff --git a/librashader-runtime-mtl/src/filter_chain.rs b/librashader-runtime-mtl/src/filter_chain.rs index e23624d..d4e611f 100644 --- a/librashader-runtime-mtl/src/filter_chain.rs +++ b/librashader-runtime-mtl/src/filter_chain.rs @@ -445,7 +445,7 @@ impl FilterChainMetal { source.wrap_mode = pass.config.wrap_mode; source.mip_filter = pass.config.filter; - let out = RenderTarget::identity(target.texture.as_ref()); + let out = RenderTarget::identity(target.texture.as_ref())?; pass.draw( &cmd, index, diff --git a/librashader-runtime-vk/src/error.rs b/librashader-runtime-vk/src/error.rs index ebbc579..2529c68 100644 --- a/librashader-runtime-vk/src/error.rs +++ b/librashader-runtime-vk/src/error.rs @@ -4,7 +4,6 @@ use librashader_preprocess::PreprocessError; use librashader_presets::ParsePresetError; use librashader_reflect::error::{ShaderCompileError, ShaderReflectError}; use librashader_runtime::image::ImageError; -use std::convert::Infallible; use thiserror::Error; /// Cumulative error type for Vulkan filter chains. @@ -29,12 +28,8 @@ pub enum FilterChainError { AllocationError(#[from] AllocationError), #[error("allocation is already freed")] AllocationDoesNotExist, -} - -impl From for FilterChainError { - fn from(_value: Infallible) -> Self { - panic!("uninhabited error") - } + #[error("unreachable")] + Infallible(#[from] std::convert::Infallible), } /// Result type for Vulkan filter chains. diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index c4c6998..4b12343 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -683,7 +683,7 @@ impl FilterChainVulkan { source.mip_filter = pass.config.filter; 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( cmd, diff --git a/librashader-runtime-vk/src/framebuffer.rs b/librashader-runtime-vk/src/framebuffer.rs index 31ec51c..5b3ac3c 100644 --- a/librashader-runtime-vk/src/framebuffer.rs +++ b/librashader-runtime-vk/src/framebuffer.rs @@ -1,7 +1,7 @@ use crate::texture::VulkanImage; use crate::{error, util}; use ash::vk; -use librashader_common::Size; +use librashader_common::{GetSize, Size}; #[derive(Clone)] pub(crate) struct OutputImage { @@ -79,3 +79,11 @@ impl OutputImage { } } } + +impl GetSize for OutputImage { + type Error = std::convert::Infallible; + + fn size(&self) -> Result, Self::Error> { + Ok(self.size) + } +} diff --git a/librashader-runtime-vk/tests/hello_triangle/mod.rs b/librashader-runtime-vk/tests/hello_triangle/mod.rs index 2df3a1e..5d54ef1 100644 --- a/librashader-runtime-vk/tests/hello_triangle/mod.rs +++ b/librashader-runtime-vk/tests/hello_triangle/mod.rs @@ -253,6 +253,7 @@ impl VulkanWindow { format: vulkan.swapchain.format.format, }, mvp: None, + size: vulkan.swapchain.extent.into(), }, cmd, frame, diff --git a/librashader-runtime-wgpu/src/error.rs b/librashader-runtime-wgpu/src/error.rs index 15a8fd2..3449c3c 100644 --- a/librashader-runtime-wgpu/src/error.rs +++ b/librashader-runtime-wgpu/src/error.rs @@ -19,6 +19,8 @@ pub enum FilterChainError { ShaderReflectError(#[from] ShaderReflectError), #[error("lut loading error")] LutLoadError(#[from] ImageError), + #[error("unreachable")] + Infallible(#[from] std::convert::Infallible), } /// Result type for wgpu filter chains. diff --git a/librashader-runtime-wgpu/src/filter_chain.rs b/librashader-runtime-wgpu/src/filter_chain.rs index f815b92..d1f5f97 100644 --- a/librashader-runtime-wgpu/src/filter_chain.rs +++ b/librashader-runtime-wgpu/src/filter_chain.rs @@ -452,7 +452,7 @@ impl FilterChainWgpu { let target = &self.output_framebuffers[index]; let output_image = WgpuOutputView::from(target); - let out = RenderTarget::identity(&output_image); + let out = RenderTarget::identity(&output_image)?; pass.draw( cmd, diff --git a/librashader-runtime-wgpu/src/texture.rs b/librashader-runtime-wgpu/src/texture.rs index c820c44..0f60b9e 100644 --- a/librashader-runtime-wgpu/src/texture.rs +++ b/librashader-runtime-wgpu/src/texture.rs @@ -1,6 +1,7 @@ use crate::error::FilterChainError; 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_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize}; use std::sync::Arc; @@ -17,7 +18,6 @@ pub struct OwnedImage { #[derive(Clone)] pub struct InputImage { - /// A handle to the `VkImage`. pub image: Arc, pub view: Arc, pub wrap_mode: WrapMode, @@ -167,3 +167,11 @@ impl ScaleFramebuffer for OwnedImage { )) } } + +impl GetSize for WgpuOutputView<'_> { + type Error = std::convert::Infallible; + + fn size(&self) -> Result, Self::Error> { + Ok(self.size) + } +} diff --git a/librashader-runtime-wgpu/tests/hello_triangle.rs b/librashader-runtime-wgpu/tests/hello_triangle.rs index bceaca9..7b10ed8 100644 --- a/librashader-runtime-wgpu/tests/hello_triangle.rs +++ b/librashader-runtime-wgpu/tests/hello_triangle.rs @@ -127,10 +127,8 @@ impl<'a> State<'a> { let preset = ShaderPreset::try_parse("../test/shaders_slang/crt/crt-royale.slangp").unwrap(); - // let preset = ShaderPreset::try_parse( - // "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", - // ) - // .unwrap(); + // let preset = + // ShaderPreset::try_parse("../test/shaders_slang/crt/crt-royale.slangp").unwrap(); let chain = FilterChainWgpu::load_from_preset( preset, @@ -300,6 +298,7 @@ impl<'a> State<'a> { filter_output.size().into(), filter_output.format(), ), + size: filter_output.size().into(), }, &mut encoder, self.frame_count, diff --git a/librashader-runtime/src/render_target.rs b/librashader-runtime/src/render_target.rs index f45c53d..df080fa 100644 --- a/librashader-runtime/src/render_target.rs +++ b/librashader-runtime/src/render_target.rs @@ -1,5 +1,5 @@ use crate::quad::{DEFAULT_MVP, IDENTITY_MVP}; -use librashader_common::Viewport; +use librashader_common::{GetSize, Size, Viewport}; use num_traits::{zero, AsPrimitive, Num}; use std::borrow::Borrow; @@ -17,21 +17,30 @@ where pub mvp: &'a [f32; 16], /// The output surface for the pass. pub output: &'a T, + /// The extent of the render target, starting from the origin defined + /// by x and y. + pub size: Size, } -impl<'a, T, C: Num> RenderTarget<'a, T, C> { +impl<'a, T: GetSize, C: Num> RenderTarget<'a, T, C> { /// Create a new render target. - pub fn new(output: &'a T, mvp: &'a [f32; 16], x: C, y: C) -> Self { - RenderTarget { output, mvp, x, y } + pub fn new(output: &'a T, mvp: &'a [f32; 16], x: C, y: C) -> Result { + Ok(RenderTarget { + output, + mvp, + x, + y, + size: output.size()?, + }) } /// Create a render target with the identity MVP. - pub fn identity(output: &'a T) -> Self { + pub fn identity(output: &'a T) -> Result { Self::offscreen(output, IDENTITY_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::new(output, mvp, zero(), zero()) } } @@ -42,21 +51,23 @@ where { /// Create a viewport render target. pub fn viewport(viewport: &'a Viewport<'a, impl Borrow>) -> Self { - Self::new( - viewport.output.borrow(), - viewport.mvp.unwrap_or(DEFAULT_MVP), - viewport.x.as_(), - viewport.y.as_(), - ) + RenderTarget { + output: viewport.output.borrow(), + mvp: viewport.mvp.unwrap_or(DEFAULT_MVP), + x: viewport.x.as_(), + y: viewport.y.as_(), + size: viewport.size, + } } /// Create a viewport render target with the given output. pub fn viewport_with_output(output: &'a T, viewport: &'a Viewport<'a, S>) -> Self { - Self::new( + RenderTarget { output, - viewport.mvp.unwrap_or(DEFAULT_MVP), - viewport.x.as_(), - viewport.y.as_(), - ) + mvp: viewport.mvp.unwrap_or(DEFAULT_MVP), + x: viewport.x.as_(), + y: viewport.y.as_(), + size: viewport.size, + } } }