rt: respect viewport extents when rendering
This commit is contained in:
parent
f0a7970b44
commit
0a87bcc657
|
@ -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>,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
})?;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue