rt(gl): account for flipped coordinate space when blitting to output
This commit is contained in:
parent
bacfbf0791
commit
623c6776f7
|
@ -10,7 +10,7 @@ use crate::texture::InputTexture;
|
||||||
use crate::util::{gl_get_version, gl_u16_to_version};
|
use crate::util::{gl_get_version, gl_u16_to_version};
|
||||||
use crate::{error, GLImage};
|
use crate::{error, GLImage};
|
||||||
use gl::types::GLuint;
|
use gl::types::GLuint;
|
||||||
use librashader_common::Viewport;
|
use librashader_common::{FilterMode, Viewport, WrapMode};
|
||||||
|
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::glsl::GlslVersion;
|
use librashader_reflect::back::glsl::GlslVersion;
|
||||||
|
@ -250,7 +250,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
T::FramebufferInterface::init(&mut back, input.size, input.format)?;
|
T::FramebufferInterface::init(&mut back, input.size, input.format)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
back.copy_from::<T::FramebufferInterface>(input)?;
|
back.copy_from::<T::FramebufferInterface>(input, false)?;
|
||||||
self.history_framebuffers.push_front(back)
|
self.history_framebuffers.push_front(back)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,12 +302,17 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// shader_gl3: 2067
|
// shader_gl3: 2067
|
||||||
let original = InputTexture {
|
// let original = InputTexture {
|
||||||
image: *input,
|
// image: *input,
|
||||||
filter,
|
// filter,
|
||||||
mip_filter: filter,
|
// mip_filter: filter,
|
||||||
wrap_mode,
|
// wrap_mode,
|
||||||
};
|
// };
|
||||||
|
|
||||||
|
let mut flipped = T::FramebufferInterface::new(1);
|
||||||
|
flipped.copy_from::<T::FramebufferInterface>(&input, true)?;
|
||||||
|
|
||||||
|
let original = flipped.as_texture(filter, wrap_mode);
|
||||||
|
|
||||||
let mut source = original;
|
let mut source = original;
|
||||||
|
|
||||||
|
@ -363,9 +368,19 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.draw_quad.bind_vertices(QuadType::Final);
|
self.draw_quad.bind_vertices(QuadType::Final);
|
||||||
|
|
||||||
// try to hint the optimizer
|
// try to hint the optimizer
|
||||||
assert_eq!(last.len(), 1);
|
assert_eq!(last.len(), 1);
|
||||||
if let Some(pass) = last.iter_mut().next() {
|
if let Some(pass) = last.iter_mut().next() {
|
||||||
|
// Need to flip the output, so we'll render to a backbuffer before blitting back to the viewport.
|
||||||
|
let mut output = T::FramebufferInterface::new(1);
|
||||||
|
output.right_size::<T::FramebufferInterface>(
|
||||||
|
&viewport
|
||||||
|
.output
|
||||||
|
.as_texture(FilterMode::Linear, WrapMode::ClampToEdge)
|
||||||
|
.image,
|
||||||
|
)?;
|
||||||
|
|
||||||
source.filter = pass.config.filter;
|
source.filter = pass.config.filter;
|
||||||
source.mip_filter = pass.config.filter;
|
source.mip_filter = pass.config.filter;
|
||||||
source.wrap_mode = pass.config.wrap_mode;
|
source.wrap_mode = pass.config.wrap_mode;
|
||||||
|
@ -378,11 +393,22 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
viewport,
|
viewport,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
RenderTarget::viewport(viewport),
|
RenderTarget::viewport_with_output(&output, viewport),
|
||||||
);
|
);
|
||||||
self.common.output_textures[passes_len - 1] = viewport
|
self.common.output_textures[passes_len - 1] =
|
||||||
.output
|
output.as_texture(pass.config.filter, pass.config.wrap_mode);
|
||||||
.as_texture(pass.config.filter, pass.config.wrap_mode);
|
|
||||||
|
// SAFETY: viewport should be the same size as output texture.
|
||||||
|
unsafe {
|
||||||
|
viewport
|
||||||
|
.output
|
||||||
|
.copy_from_unchecked::<T::FramebufferInterface>(
|
||||||
|
&output
|
||||||
|
.as_texture(pass.config.filter, pass.config.wrap_mode)
|
||||||
|
.image,
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// swap feedback framebuffers with output
|
// swap feedback framebuffers with output
|
||||||
|
@ -392,7 +418,6 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
);
|
);
|
||||||
|
|
||||||
self.push_history(input)?;
|
self.push_history(input)?;
|
||||||
|
|
||||||
self.draw_quad.unbind_vertices();
|
self.draw_quad.unbind_vertices();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -67,8 +67,34 @@ impl GLFramebuffer {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn copy_from<T: FramebufferInterface>(&mut self, image: &GLImage) -> Result<()> {
|
pub(crate) unsafe fn copy_from_unchecked<T: FramebufferInterface>(
|
||||||
T::copy_from(self, image)
|
&self,
|
||||||
|
image: &GLImage,
|
||||||
|
flip_y: bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
// SAFETY: checked size above.
|
||||||
|
unsafe { T::copy_from_unchecked(self, image, flip_y) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn right_size<T: FramebufferInterface>(&mut self, image: &GLImage) -> Result<()> {
|
||||||
|
if image.size != self.size || image.format != self.format {
|
||||||
|
T::init(self, image.size, image.format)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn copy_from<T: FramebufferInterface>(
|
||||||
|
&mut self,
|
||||||
|
image: &GLImage,
|
||||||
|
flip_y: bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
if image.size != self.size || image.format != self.format {
|
||||||
|
T::init(self, image.size, image.format)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: checked size above.
|
||||||
|
unsafe { self.copy_from_unchecked::<T>(image, flip_y) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn as_texture(&self, filter: FilterMode, wrap_mode: WrapMode) -> InputTexture {
|
pub(crate) fn as_texture(&self, filter: FilterMode, wrap_mode: WrapMode) -> InputTexture {
|
||||||
|
|
|
@ -80,12 +80,8 @@ impl FramebufferInterface for Gl3Framebuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn copy_from(fb: &mut GLFramebuffer, image: &GLImage) -> Result<()> {
|
|
||||||
// todo: may want to use a shader and draw a quad to be faster.
|
|
||||||
if image.size != fb.size || image.format != fb.format {
|
|
||||||
Self::init(fb, image.size, image.format)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
unsafe fn copy_from_unchecked(fb: &GLFramebuffer, image: &GLImage, flip_y: bool) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, fb.fbo);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, fb.fbo);
|
||||||
|
|
||||||
|
@ -112,9 +108,9 @@ impl FramebufferInterface for Gl3Framebuffer {
|
||||||
fb.size.width as GLint,
|
fb.size.width as GLint,
|
||||||
fb.size.height as GLint,
|
fb.size.height as GLint,
|
||||||
0,
|
0,
|
||||||
0,
|
if flip_y { fb.size.height as GLint } else { 0 },
|
||||||
fb.size.width as GLint,
|
fb.size.width as GLint,
|
||||||
fb.size.height as GLint,
|
if flip_y { 0 } else { fb.size.height as GLint },
|
||||||
gl::COLOR_BUFFER_BIT,
|
gl::COLOR_BUFFER_BIT,
|
||||||
gl::NEAREST,
|
gl::NEAREST,
|
||||||
);
|
);
|
||||||
|
|
|
@ -77,17 +77,12 @@ impl FramebufferInterface for Gl46Framebuffer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn copy_from(fb: &mut GLFramebuffer, image: &GLImage) -> Result<()> {
|
unsafe fn copy_from_unchecked(fb: &GLFramebuffer, image: &GLImage, flip_y: bool) -> Result<()> {
|
||||||
// todo: confirm this behaviour for unbound image.
|
// todo: confirm this behaviour for unbound image.
|
||||||
if image.handle == 0 {
|
if image.handle == 0 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: may want to use a shader and draw a quad to be faster.
|
|
||||||
if image.size != fb.size || image.format != fb.format {
|
|
||||||
Self::init(fb, image.size, image.format)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// gl::NamedFramebufferDrawBuffer(fb.handle, gl::COLOR_ATTACHMENT1);
|
// gl::NamedFramebufferDrawBuffer(fb.handle, gl::COLOR_ATTACHMENT1);
|
||||||
gl::NamedFramebufferReadBuffer(image.handle, gl::COLOR_ATTACHMENT0);
|
gl::NamedFramebufferReadBuffer(image.handle, gl::COLOR_ATTACHMENT0);
|
||||||
|
@ -101,9 +96,9 @@ impl FramebufferInterface for Gl46Framebuffer {
|
||||||
image.size.width as GLint,
|
image.size.width as GLint,
|
||||||
image.size.height as GLint,
|
image.size.height as GLint,
|
||||||
0,
|
0,
|
||||||
0,
|
if flip_y { fb.size.height as GLint } else { 0 },
|
||||||
fb.size.width as GLint,
|
fb.size.width as GLint,
|
||||||
fb.size.height as GLint,
|
if flip_y { 0 } else { fb.size.height as GLint },
|
||||||
gl::COLOR_BUFFER_BIT,
|
gl::COLOR_BUFFER_BIT,
|
||||||
gl::NEAREST,
|
gl::NEAREST,
|
||||||
);
|
);
|
||||||
|
|
|
@ -95,7 +95,7 @@ pub(crate) trait FramebufferInterface {
|
||||||
mipmap: bool,
|
mipmap: bool,
|
||||||
) -> Result<Size<u32>>;
|
) -> Result<Size<u32>>;
|
||||||
fn clear<const REBIND: bool>(fb: &GLFramebuffer);
|
fn clear<const REBIND: bool>(fb: &GLFramebuffer);
|
||||||
fn copy_from(fb: &mut GLFramebuffer, image: &GLImage) -> Result<()>;
|
unsafe fn copy_from_unchecked(fb: &GLFramebuffer, image: &GLImage, flip_y: bool) -> Result<()>;
|
||||||
fn init(fb: &mut GLFramebuffer, size: Size<u32>, format: impl Into<GLenum>) -> Result<()>;
|
fn init(fb: &mut GLFramebuffer, size: Size<u32>, format: impl Into<GLenum>) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ fn triangle_gl() {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut filter = FilterChainGL::load_from_path(
|
let mut filter = FilterChainGL::load_from_path(
|
||||||
"../test/shaders_slang/crt/crt-royale.slangp",
|
"../test/shaders_slang/crt/crt-hyllian.slangp",
|
||||||
|
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
||||||
Some(&FilterChainOptionsGL {
|
Some(&FilterChainOptionsGL {
|
||||||
glsl_version: 0,
|
glsl_version: 0,
|
||||||
use_dsa: false,
|
use_dsa: false,
|
||||||
|
@ -30,7 +31,7 @@ fn triangle_gl46() {
|
||||||
let mut filter = FilterChainGL::load_from_path(
|
let mut filter = FilterChainGL::load_from_path(
|
||||||
// "../test/slang-shaders/vhs/VHSPro.slangp",
|
// "../test/slang-shaders/vhs/VHSPro.slangp",
|
||||||
// "../test/slang-shaders/test/history.slangp",
|
// "../test/slang-shaders/test/history.slangp",
|
||||||
"../test/shaders_slang/crt/crt-royale.slangp",
|
"../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
||||||
// "../test/shadersslang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
// "../test/shadersslang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
||||||
Some(&FilterChainOptionsGL {
|
Some(&FilterChainOptionsGL {
|
||||||
glsl_version: 0,
|
glsl_version: 0,
|
||||||
|
|
Loading…
Reference in a new issue