diff --git a/librashader-common/src/lib.rs b/librashader-common/src/lib.rs index 1880559..efd2caa 100644 --- a/librashader-common/src/lib.rs +++ b/librashader-common/src/lib.rs @@ -40,6 +40,7 @@ pub use viewport::Viewport; use num_traits::{AsPrimitive, Num}; use std::convert::Infallible; +use std::ops::{Add, Sub}; use std::str::FromStr; #[repr(u32)] @@ -200,6 +201,51 @@ impl Size { } } +impl> Sub for Size { + type Output = Size; + + fn sub(self, rhs: Self) -> Self::Output { + Self { + width: self.width - rhs.width, + height: self.height - rhs.height + } + } +} + +impl + Copy> Sub for Size { + type Output = Size; + + fn sub(self, rhs: T) -> Self::Output { + Self { + width: self.width - rhs, + height: self.height - rhs + } + } +} + + +impl> Add for Size { + type Output = Size; + + fn add(self, rhs: Self) -> Self::Output { + Self { + width: self.width + rhs.width, + height: self.height + rhs.height + } + } +} + +impl + Copy> Add for Size { + type Output = Size; + + fn add(self, rhs: T) -> Self::Output { + Self { + width: self.width + rhs, + height: self.height + rhs + } + } +} + impl From> for [f32; 4] where T: Copy + AsPrimitive, diff --git a/librashader-common/src/viewport.rs b/librashader-common/src/viewport.rs index 8456cfe..84b7bbf 100644 --- a/librashader-common/src/viewport.rs +++ b/librashader-common/src/viewport.rs @@ -1,8 +1,16 @@ use crate::Size; /// The rendering output of a filter chain. +/// +/// Viewport coordinates are relative to the coordinate system of the +/// target runtime. For correct results, `x` and `y` should almost always be +/// 0, and `size` should be the same as the size of the output texture. +/// +/// Size uniforms will always be passed the full size of the output texture, +/// regardless of the user-specified viewport size. pub struct Viewport<'a, T> { - /// The x offset to start rendering from. + /// The x offset to start rendering from. For correct results, this should almost + /// always be 0 to indicate the origin. pub x: f32, /// The y offset to begin rendering from. pub y: f32, diff --git a/librashader-runtime-d3d11/src/filter_pass.rs b/librashader-runtime-d3d11/src/filter_pass.rs index a17b94b..f11b2e2 100644 --- a/librashader-runtime-d3d11/src/filter_pass.rs +++ b/librashader-runtime-d3d11/src/filter_pass.rs @@ -1,3 +1,4 @@ +use windows::Win32::Foundation::RECT; use crate::filter_chain::FilterCommon; use crate::options::FrameOptionsD3D11; use crate::texture::InputTexture; @@ -253,18 +254,24 @@ impl FilterPass { ctx.RSSetViewports(Some(&[D3D11_VIEWPORT { TopLeftX: output.x, TopLeftY: output.y, - Width: output_size.width as f32, - Height: output_size.height as f32, + Width: output.size.width as f32, + Height: output.size.height as f32, MinDepth: 0.0, MaxDepth: 1.0, - }])) + }])); + ctx.RSSetScissorRects(Some(&[RECT { + left: output.x as i32, + top: output.y as i32, + right: output.size.width as i32, + bottom: output.size.height as i32, + }])); } parent.draw_quad.draw_quad(ctx, vbo_type); unsafe { // unbind resources. - ctx.PSSetShaderResources(0, Some(std::mem::transmute(NULL_TEXTURES.as_ref()))); + ctx.PSSetShaderResources(0, Some(NULL_TEXTURES)); ctx.OMSetRenderTargets(None, None); } Ok(()) diff --git a/librashader-runtime-d3d11/tests/hello_triangle/mod.rs b/librashader-runtime-d3d11/tests/hello_triangle/mod.rs index f713d26..98120eb 100644 --- a/librashader-runtime-d3d11/tests/hello_triangle/mod.rs +++ b/librashader-runtime-d3d11/tests/hello_triangle/mod.rs @@ -570,17 +570,20 @@ pub mod d3d11_hello_triangle { // eprintln!("w: {} h: {}", backbuffer_desc.Width, backbuffer_desc.Height); let output = resources.backbuffer_rtv.as_ref().unwrap().clone(); - let size = output.size().unwrap(); + let size: Size = output.size().unwrap(); self.filter .frame( None, &srv, &Viewport { - x: 0f32, - y: 0f32, + x: 100f32, + y: 100f32, output, mvp: None, - size, + size: Size { + width: size.width - 200, + height: size.height - 200, + }, }, resources.frame_count, None, diff --git a/librashader-runtime-d3d12/src/filter_pass.rs b/librashader-runtime-d3d12/src/filter_pass.rs index 28dc532..70a5309 100644 --- a/librashader-runtime-d3d12/src/filter_pass.rs +++ b/librashader-runtime-d3d12/src/filter_pass.rs @@ -206,17 +206,17 @@ impl FilterPass { cmd.RSSetViewports(&[D3D12_VIEWPORT { TopLeftX: output.x, TopLeftY: output.y, - Width: output.output.size.width as f32, - Height: output.output.size.height as f32, + Width: output.size.width as f32, + Height: output.size.height as f32, MinDepth: 0.0, MaxDepth: 1.0, }]); cmd.RSSetScissorRects(&[RECT { - left: 0, - top: 0, - right: output.output.size.width as i32, - bottom: output.output.size.height as i32, + left: output.x as i32, + top: output.y as i32, + right: output.size.width as i32, + bottom: output.size.height as i32, }]); parent.draw_quad.draw_quad(&cmd, vbo_type) diff --git a/librashader-runtime-d3d9/src/filter_pass.rs b/librashader-runtime-d3d9/src/filter_pass.rs index c127248..8761316 100644 --- a/librashader-runtime-d3d9/src/filter_pass.rs +++ b/librashader-runtime-d3d9/src/filter_pass.rs @@ -193,8 +193,8 @@ impl FilterPass { device.SetViewport(&D3DVIEWPORT9 { X: output.x as u32, Y: output.y as u32, - Width: output_size.width, - Height: output_size.height, + Width: output.size.width, + Height: output.size.height, MinZ: 0.0, MaxZ: 1.0, })?; diff --git a/librashader-runtime-gl/src/filter_pass.rs b/librashader-runtime-gl/src/filter_pass.rs index 071bef2..7a52072 100644 --- a/librashader-runtime-gl/src/filter_pass.rs +++ b/librashader-runtime-gl/src/filter_pass.rs @@ -133,12 +133,11 @@ impl FilterPass { unsafe { framebuffer.clear::(); - let framebuffer_size = framebuffer.size; parent.context.viewport( output.x, output.y, - framebuffer_size.width as i32, - framebuffer_size.height as i32, + output.size.width as i32, + output.size.height as i32, ); if framebuffer.format == glow::SRGB8_ALPHA8 { diff --git a/librashader-runtime-mtl/src/graphics_pipeline.rs b/librashader-runtime-mtl/src/graphics_pipeline.rs index 855a428..4920ed8 100644 --- a/librashader-runtime-mtl/src/graphics_pipeline.rs +++ b/librashader-runtime-mtl/src/graphics_pipeline.rs @@ -207,15 +207,15 @@ impl MetalGraphicsPipeline { rpass.setScissorRect(MTLScissorRect { x: output.x as usize, y: output.y as usize, - width: output.output.width(), - height: output.output.height(), + width: output.size.width as usize, + height: output.size.height as usize }); rpass.setViewport(MTLViewport { originX: output.x as f64, originY: output.y as f64, - width: output.output.width() as f64, - height: output.output.height() as f64, + width: output.size.width as f64, + height: output.size.height as f64, znear: 0.0, zfar: 1.0, }); diff --git a/librashader-runtime-vk/src/filter_pass.rs b/librashader-runtime-vk/src/filter_pass.rs index cb3d7f6..8883b2a 100644 --- a/librashader-runtime-vk/src/filter_pass.rs +++ b/librashader-runtime-vk/src/filter_pass.rs @@ -183,13 +183,13 @@ impl FilterPass { x: output.x as i32, y: output.y as i32, }, - extent: output.output.size.into(), + extent: output.size.into(), }], ); parent .device - .cmd_set_viewport(cmd, 0, &[output.output.size.into()]); + .cmd_set_viewport(cmd, 0, &[output.size.into()]); parent.draw_quad.draw_quad(&parent.device, cmd, vbo_type); self.graphics_pipeline.end_rendering(cmd); } diff --git a/librashader-runtime-vk/tests/hello_triangle/mod.rs b/librashader-runtime-vk/tests/hello_triangle/mod.rs index 5d54ef1..9241c7c 100644 --- a/librashader-runtime-vk/tests/hello_triangle/mod.rs +++ b/librashader-runtime-vk/tests/hello_triangle/mod.rs @@ -23,7 +23,7 @@ use swapchain::VulkanSwapchain; use syncobjects::SyncObjects; use vulkan_base::VulkanBase; -use librashader_common::Viewport; +use librashader_common::{Size, Viewport}; use librashader_runtime_vk::options::FrameOptionsVulkan; use winit::event::{Event, WindowEvent}; diff --git a/librashader-runtime-wgpu/src/graphics_pipeline.rs b/librashader-runtime-wgpu/src/graphics_pipeline.rs index 4cc16ce..4392a58 100644 --- a/librashader-runtime-wgpu/src/graphics_pipeline.rs +++ b/librashader-runtime-wgpu/src/graphics_pipeline.rs @@ -310,15 +310,15 @@ impl WgpuGraphicsPipeline { render_pass.set_scissor_rect( output.x as u32, output.y as u32, - output.output.size.width, - output.output.size.height, + output.size.width, + output.size.height, ); render_pass.set_viewport( output.x, output.y, - output.output.size.width as f32, - output.output.size.height as f32, + output.size.width as f32, + output.size.height as f32, 0.0, 1.0, ); diff --git a/librashader-runtime-wgpu/tests/hello_triangle.rs b/librashader-runtime-wgpu/tests/hello_triangle.rs index 7b10ed8..da0e169 100644 --- a/librashader-runtime-wgpu/tests/hello_triangle.rs +++ b/librashader-runtime-wgpu/tests/hello_triangle.rs @@ -4,7 +4,7 @@ use winit::{ window::{Window, WindowBuilder}, }; -use librashader_common::Viewport; +use librashader_common::{Size, Viewport}; use librashader_presets::ShaderPreset; use librashader_runtime_wgpu::FilterChainWgpu; use wgpu::util::DeviceExt; @@ -290,15 +290,15 @@ impl<'a> State<'a> { .frame( Arc::clone(&render_output), &Viewport { - x: 0.0, - y: 0.0, + x: 100.0, + y: 100.0, mvp: None, output: librashader_runtime_wgpu::WgpuOutputView::new_from_raw( &filter_view, filter_output.size().into(), filter_output.format(), ), - size: filter_output.size().into(), + size: (Size::from(filter_output.size())) - 200, }, &mut encoder, self.frame_count,