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 num_traits::{AsPrimitive, Num};
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
use std::ops::{Add, Sub};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[repr(u32)]
|
#[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]
|
impl<T> From<Size<T>> for [f32; 4]
|
||||||
where
|
where
|
||||||
T: Copy + AsPrimitive<f32>,
|
T: Copy + AsPrimitive<f32>,
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
use crate::Size;
|
use crate::Size;
|
||||||
|
|
||||||
/// The rendering output of a filter chain.
|
/// 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> {
|
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,
|
pub x: f32,
|
||||||
/// The y offset to begin rendering from.
|
/// The y offset to begin rendering from.
|
||||||
pub y: f32,
|
pub y: f32,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use windows::Win32::Foundation::RECT;
|
||||||
use crate::filter_chain::FilterCommon;
|
use crate::filter_chain::FilterCommon;
|
||||||
use crate::options::FrameOptionsD3D11;
|
use crate::options::FrameOptionsD3D11;
|
||||||
use crate::texture::InputTexture;
|
use crate::texture::InputTexture;
|
||||||
|
@ -253,18 +254,24 @@ impl FilterPass {
|
||||||
ctx.RSSetViewports(Some(&[D3D11_VIEWPORT {
|
ctx.RSSetViewports(Some(&[D3D11_VIEWPORT {
|
||||||
TopLeftX: output.x,
|
TopLeftX: output.x,
|
||||||
TopLeftY: output.y,
|
TopLeftY: output.y,
|
||||||
Width: output_size.width as f32,
|
Width: output.size.width as f32,
|
||||||
Height: output_size.height as f32,
|
Height: output.size.height as f32,
|
||||||
MinDepth: 0.0,
|
MinDepth: 0.0,
|
||||||
MaxDepth: 1.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);
|
parent.draw_quad.draw_quad(ctx, vbo_type);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// unbind resources.
|
// unbind resources.
|
||||||
ctx.PSSetShaderResources(0, Some(std::mem::transmute(NULL_TEXTURES.as_ref())));
|
ctx.PSSetShaderResources(0, Some(NULL_TEXTURES));
|
||||||
ctx.OMSetRenderTargets(None, None);
|
ctx.OMSetRenderTargets(None, None);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -570,17 +570,20 @@ pub mod d3d11_hello_triangle {
|
||||||
|
|
||||||
// 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 output = resources.backbuffer_rtv.as_ref().unwrap().clone();
|
||||||
let size = output.size().unwrap();
|
let size: Size<u32> = output.size().unwrap();
|
||||||
self.filter
|
self.filter
|
||||||
.frame(
|
.frame(
|
||||||
None,
|
None,
|
||||||
&srv,
|
&srv,
|
||||||
&Viewport {
|
&Viewport {
|
||||||
x: 0f32,
|
x: 100f32,
|
||||||
y: 0f32,
|
y: 100f32,
|
||||||
output,
|
output,
|
||||||
mvp: None,
|
mvp: None,
|
||||||
size,
|
size: Size {
|
||||||
|
width: size.width - 200,
|
||||||
|
height: size.height - 200,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
resources.frame_count,
|
resources.frame_count,
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -206,17 +206,17 @@ impl FilterPass {
|
||||||
cmd.RSSetViewports(&[D3D12_VIEWPORT {
|
cmd.RSSetViewports(&[D3D12_VIEWPORT {
|
||||||
TopLeftX: output.x,
|
TopLeftX: output.x,
|
||||||
TopLeftY: output.y,
|
TopLeftY: output.y,
|
||||||
Width: output.output.size.width as f32,
|
Width: output.size.width as f32,
|
||||||
Height: output.output.size.height as f32,
|
Height: output.size.height as f32,
|
||||||
MinDepth: 0.0,
|
MinDepth: 0.0,
|
||||||
MaxDepth: 1.0,
|
MaxDepth: 1.0,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
cmd.RSSetScissorRects(&[RECT {
|
cmd.RSSetScissorRects(&[RECT {
|
||||||
left: 0,
|
left: output.x as i32,
|
||||||
top: 0,
|
top: output.y as i32,
|
||||||
right: output.output.size.width as i32,
|
right: output.size.width as i32,
|
||||||
bottom: output.output.size.height as i32,
|
bottom: output.size.height as i32,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
parent.draw_quad.draw_quad(&cmd, vbo_type)
|
parent.draw_quad.draw_quad(&cmd, vbo_type)
|
||||||
|
|
|
@ -193,8 +193,8 @@ impl FilterPass {
|
||||||
device.SetViewport(&D3DVIEWPORT9 {
|
device.SetViewport(&D3DVIEWPORT9 {
|
||||||
X: output.x as u32,
|
X: output.x as u32,
|
||||||
Y: output.y as u32,
|
Y: output.y as u32,
|
||||||
Width: output_size.width,
|
Width: output.size.width,
|
||||||
Height: output_size.height,
|
Height: output.size.height,
|
||||||
MinZ: 0.0,
|
MinZ: 0.0,
|
||||||
MaxZ: 1.0,
|
MaxZ: 1.0,
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -133,12 +133,11 @@ impl<T: GLInterface> FilterPass<T> {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
framebuffer.clear::<T::FramebufferInterface, false>();
|
framebuffer.clear::<T::FramebufferInterface, false>();
|
||||||
let framebuffer_size = framebuffer.size;
|
|
||||||
parent.context.viewport(
|
parent.context.viewport(
|
||||||
output.x,
|
output.x,
|
||||||
output.y,
|
output.y,
|
||||||
framebuffer_size.width as i32,
|
output.size.width as i32,
|
||||||
framebuffer_size.height as i32,
|
output.size.height as i32,
|
||||||
);
|
);
|
||||||
|
|
||||||
if framebuffer.format == glow::SRGB8_ALPHA8 {
|
if framebuffer.format == glow::SRGB8_ALPHA8 {
|
||||||
|
|
|
@ -207,15 +207,15 @@ impl MetalGraphicsPipeline {
|
||||||
rpass.setScissorRect(MTLScissorRect {
|
rpass.setScissorRect(MTLScissorRect {
|
||||||
x: output.x as usize,
|
x: output.x as usize,
|
||||||
y: output.y as usize,
|
y: output.y as usize,
|
||||||
width: output.output.width(),
|
width: output.size.width as usize,
|
||||||
height: output.output.height(),
|
height: output.size.height as usize
|
||||||
});
|
});
|
||||||
|
|
||||||
rpass.setViewport(MTLViewport {
|
rpass.setViewport(MTLViewport {
|
||||||
originX: output.x as f64,
|
originX: output.x as f64,
|
||||||
originY: output.y as f64,
|
originY: output.y as f64,
|
||||||
width: output.output.width() as f64,
|
width: output.size.width as f64,
|
||||||
height: output.output.height() as f64,
|
height: output.size.height as f64,
|
||||||
znear: 0.0,
|
znear: 0.0,
|
||||||
zfar: 1.0,
|
zfar: 1.0,
|
||||||
});
|
});
|
||||||
|
|
|
@ -183,13 +183,13 @@ impl FilterPass {
|
||||||
x: output.x as i32,
|
x: output.x as i32,
|
||||||
y: output.y as i32,
|
y: output.y as i32,
|
||||||
},
|
},
|
||||||
extent: output.output.size.into(),
|
extent: output.size.into(),
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
parent
|
parent
|
||||||
.device
|
.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);
|
parent.draw_quad.draw_quad(&parent.device, cmd, vbo_type);
|
||||||
self.graphics_pipeline.end_rendering(cmd);
|
self.graphics_pipeline.end_rendering(cmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ use swapchain::VulkanSwapchain;
|
||||||
use syncobjects::SyncObjects;
|
use syncobjects::SyncObjects;
|
||||||
use vulkan_base::VulkanBase;
|
use vulkan_base::VulkanBase;
|
||||||
|
|
||||||
use librashader_common::Viewport;
|
use librashader_common::{Size, Viewport};
|
||||||
|
|
||||||
use librashader_runtime_vk::options::FrameOptionsVulkan;
|
use librashader_runtime_vk::options::FrameOptionsVulkan;
|
||||||
use winit::event::{Event, WindowEvent};
|
use winit::event::{Event, WindowEvent};
|
||||||
|
|
|
@ -310,15 +310,15 @@ impl WgpuGraphicsPipeline {
|
||||||
render_pass.set_scissor_rect(
|
render_pass.set_scissor_rect(
|
||||||
output.x as u32,
|
output.x as u32,
|
||||||
output.y as u32,
|
output.y as u32,
|
||||||
output.output.size.width,
|
output.size.width,
|
||||||
output.output.size.height,
|
output.size.height,
|
||||||
);
|
);
|
||||||
|
|
||||||
render_pass.set_viewport(
|
render_pass.set_viewport(
|
||||||
output.x,
|
output.x,
|
||||||
output.y,
|
output.y,
|
||||||
output.output.size.width as f32,
|
output.size.width as f32,
|
||||||
output.output.size.height as f32,
|
output.size.height as f32,
|
||||||
0.0,
|
0.0,
|
||||||
1.0,
|
1.0,
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,7 +4,7 @@ use winit::{
|
||||||
window::{Window, WindowBuilder},
|
window::{Window, WindowBuilder},
|
||||||
};
|
};
|
||||||
|
|
||||||
use librashader_common::Viewport;
|
use librashader_common::{Size, Viewport};
|
||||||
use librashader_presets::ShaderPreset;
|
use librashader_presets::ShaderPreset;
|
||||||
use librashader_runtime_wgpu::FilterChainWgpu;
|
use librashader_runtime_wgpu::FilterChainWgpu;
|
||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
|
@ -290,15 +290,15 @@ impl<'a> State<'a> {
|
||||||
.frame(
|
.frame(
|
||||||
Arc::clone(&render_output),
|
Arc::clone(&render_output),
|
||||||
&Viewport {
|
&Viewport {
|
||||||
x: 0.0,
|
x: 100.0,
|
||||||
y: 0.0,
|
y: 100.0,
|
||||||
mvp: None,
|
mvp: None,
|
||||||
output: librashader_runtime_wgpu::WgpuOutputView::new_from_raw(
|
output: librashader_runtime_wgpu::WgpuOutputView::new_from_raw(
|
||||||
&filter_view,
|
&filter_view,
|
||||||
filter_output.size().into(),
|
filter_output.size().into(),
|
||||||
filter_output.format(),
|
filter_output.format(),
|
||||||
),
|
),
|
||||||
size: filter_output.size().into(),
|
size: (Size::from(filter_output.size())) - 200,
|
||||||
},
|
},
|
||||||
&mut encoder,
|
&mut encoder,
|
||||||
self.frame_count,
|
self.frame_count,
|
||||||
|
|
Loading…
Reference in a new issue