rt: respect viewport extents when rendering

This commit is contained in:
chyyran 2024-08-13 01:20:21 -04:00 committed by Ronny Chan
parent f0a7970b44
commit 0a87bcc657
12 changed files with 98 additions and 35 deletions

View file

@ -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<T> Size<T> {
}
}
impl<T: Sub<Output=T>> Sub for Size<T> {
type Output = Size<T>;
fn sub(self, rhs: Self) -> Self::Output {
Self {
width: self.width - rhs.width,
height: self.height - rhs.height
}
}
}
impl<T: Sub<T, Output=T> + Copy> Sub<T> for Size<T> {
type Output = Size<T>;
fn sub(self, rhs: T) -> Self::Output {
Self {
width: self.width - rhs,
height: self.height - rhs
}
}
}
impl<T: Add<Output=T>> Add for Size<T> {
type Output = Size<T>;
fn add(self, rhs: Self) -> Self::Output {
Self {
width: self.width + rhs.width,
height: self.height + rhs.height
}
}
}
impl<T: Add<T, Output=T> + Copy> Add<T> for Size<T> {
type Output = Size<T>;
fn add(self, rhs: T) -> Self::Output {
Self {
width: self.width + rhs,
height: self.height + rhs
}
}
}
impl<T> From<Size<T>> for [f32; 4]
where
T: Copy + AsPrimitive<f32>,

View file

@ -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,

View file

@ -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(())

View file

@ -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<u32> = 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,

View file

@ -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)

View file

@ -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,
})?;

View file

@ -133,12 +133,11 @@ impl<T: GLInterface> FilterPass<T> {
unsafe {
framebuffer.clear::<T::FramebufferInterface, false>();
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 {

View file

@ -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,
});

View file

@ -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);
}

View file

@ -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};

View file

@ -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,
);

View file

@ -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,