rt(gl): ensure framebuffers are bound

This commit is contained in:
chyyran 2024-09-24 01:59:01 -04:00 committed by Ronny Chan
parent 97ad0d64bf
commit e7fe96520e
10 changed files with 82 additions and 41 deletions

View file

@ -10,7 +10,7 @@ use thiserror::Error;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum FilterChainError {
#[error("fbo initialization error")]
#[error("fbo initialization error {0:x}")]
FramebufferInit(u32),
#[error("SPIRV reflection error")]
SpirvCrossReflectError(#[from] spirv_cross2::SpirvCrossError),

View file

@ -377,7 +377,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
&original,
&source,
RenderTarget::identity(target)?,
);
)?;
let target = target.as_texture(pass.config.filter, pass.config.wrap_mode);
self.common.output_textures[index] = target;
@ -409,7 +409,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
&original,
&source,
RenderTarget::viewport_with_output(target, viewport),
);
)?;
}
pass.draw(
@ -421,7 +421,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
&original,
&source,
RenderTarget::viewport_with_output(final_viewport, viewport),
);
)?;
self.common.output_textures[passes_len - 1] = viewport
.output
.as_texture(pass.config.filter, pass.config.wrap_mode);

View file

@ -15,7 +15,7 @@ use crate::filter_chain::FilterCommon;
use crate::gl::{BindTexture, GLFramebuffer, GLInterface, UboRing};
use crate::options::FrameOptionsGL;
use crate::samplers::SamplerSet;
use crate::GLImage;
use crate::{error, GLImage};
use crate::texture::InputTexture;
@ -86,7 +86,7 @@ impl<T: GLInterface> FilterPass<T> {
original: &InputTexture,
source: &InputTexture,
output: RenderTarget<GLFramebuffer, i32>,
) {
) -> error::Result<()> {
let framebuffer = output.output;
if self.config.mipmap_input && !parent.disable_mipmaps {
@ -94,9 +94,7 @@ impl<T: GLInterface> FilterPass<T> {
}
unsafe {
parent
.context
.bind_framebuffer(glow::FRAMEBUFFER, Some(framebuffer.fbo));
framebuffer.bind::<T::FramebufferInterface>()?;
parent.context.use_program(Some(self.program));
}
@ -154,6 +152,8 @@ impl<T: GLInterface> FilterPass<T> {
parent.context.disable(glow::FRAMEBUFFER_SRGB);
parent.context.bind_framebuffer(glow::FRAMEBUFFER, None);
}
Ok(())
}
}

View file

@ -87,6 +87,10 @@ impl GLFramebuffer {
wrap_mode,
}
}
pub(crate) fn bind<T: FramebufferInterface>(&self) -> Result<()> {
T::bind(self)
}
}
/// A state-checked wrapper around a raw framebuffer, used exclusively for output images.

View file

@ -290,4 +290,23 @@ impl FramebufferInterface for Gl3Framebuffer {
Ok(())
}
fn bind(fb: &GLFramebuffer) -> Result<()> {
unsafe {
fb.ctx.bind_framebuffer(glow::FRAMEBUFFER, Some(fb.fbo));
fb.ctx.framebuffer_texture_2d(
glow::FRAMEBUFFER,
glow::COLOR_ATTACHMENT0,
glow::TEXTURE_2D,
fb.image,
0,
);
let status = fb.ctx.check_framebuffer_status(glow::FRAMEBUFFER);
if status != glow::FRAMEBUFFER_COMPLETE {
return Err(FilterChainError::FramebufferInit(status));
}
}
Ok(())
}
}

View file

@ -236,4 +236,16 @@ impl FramebufferInterface for Gl46Framebuffer {
}
Ok(())
}
fn bind(fb: &GLFramebuffer) -> Result<()> {
unsafe {
fb.ctx.bind_framebuffer(glow::FRAMEBUFFER, Some(fb.fbo));
let status = fb.ctx.check_framebuffer_status(glow::FRAMEBUFFER);
if status != glow::FRAMEBUFFER_COMPLETE {
return Err(FilterChainError::FramebufferInit(status));
}
}
Ok(())
}
}

View file

@ -120,7 +120,11 @@ pub(crate) trait FramebufferInterface {
let size = source_size.scale_viewport(scaling, *viewport_size, *original_size);
if fb.size != size || (mipmap && fb.max_levels == 1) || (!mipmap && fb.max_levels != 1) {
if fb.size != size
|| (mipmap && fb.max_levels == 1)
|| (!mipmap && fb.max_levels != 1)
|| fb.image.is_none()
{
fb.size = size;
if mipmap {
@ -145,6 +149,7 @@ pub(crate) trait FramebufferInterface {
fn clear<const REBIND: bool>(fb: &GLFramebuffer);
fn copy_from(fb: &mut GLFramebuffer, image: &GLImage) -> Result<()>;
fn init(fb: &mut GLFramebuffer, size: Size<u32>, format: impl Into<u32>) -> Result<()>;
fn bind(fb: &GLFramebuffer) -> Result<()>;
}
pub(crate) trait BindTexture {

View file

@ -1,7 +1,7 @@
use std::sync::mpsc::Receiver;
use std::sync::Arc;
use glfw::{Context, Glfw, Window, WindowEvent};
use glfw::{fail_on_errors, Context, Glfw, GlfwReceiver, PWindow, Window, WindowEvent};
use glow::HasContext;
use librashader_common::{GetSize, Size, Viewport};
@ -14,13 +14,13 @@ const TITLE: &str = "librashader OpenGL 3.3";
pub fn setup() -> (
Glfw,
Window,
Receiver<(f64, WindowEvent)>,
PWindow,
GlfwReceiver<(f64, WindowEvent)>,
glow::Program,
glow::VertexArray,
Arc<glow::Context>,
) {
let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
let mut glfw = glfw::init(fail_on_errors!()).unwrap();
glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3));
glfw.window_hint(glfw::WindowHint::OpenGlProfile(
glfw::OpenGlProfileHint::Core,
@ -171,8 +171,8 @@ void main()
pub fn do_loop(
gl: &Arc<glow::Context>,
mut glfw: Glfw,
mut window: Window,
events: Receiver<(f64, WindowEvent)>,
mut window: PWindow,
events: GlfwReceiver<(f64, WindowEvent)>,
triangle_program: glow::Program,
triangle_vao: glow::VertexArray,
filter: &mut FilterChainGL,
@ -183,7 +183,7 @@ pub fn do_loop(
let quad_vbuf;
let output_texture;
let output_framebuffer_handle;
// let output_framebuffer_handle;
let output_quad_vbuf;
unsafe {
@ -270,10 +270,11 @@ pub fn do_loop(
}
unsafe {
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
// do frmaebuffer
output_framebuffer_handle = gl.create_framebuffer().unwrap();
gl.bind_framebuffer(glow::FRAMEBUFFER, Some(output_framebuffer_handle));
// output_framebuffer_handle = gl.create_framebuffer().unwrap();
//
// gl.bind_framebuffer(glow::FRAMEBUFFER, Some(output_framebuffer_handle));
// glow::ObjectLabel(
// glow::FRAMEBUFFER,
@ -324,18 +325,18 @@ pub fn do_loop(
);
// set color attachment
gl.framebuffer_texture_2d(
glow::FRAMEBUFFER,
glow::COLOR_ATTACHMENT0,
glow::TEXTURE_2D,
Some(output_texture),
0,
);
// gl.framebuffer_texture_2d(
// glow::FRAMEBUFFER,
// glow::COLOR_ATTACHMENT0,
// glow::TEXTURE_2D,
// Some(output_texture),
// 0,
// );
gl.draw_buffer(glow::COLOR_ATTACHMENT0);
if gl.check_framebuffer_status(glow::FRAMEBUFFER) != glow::FRAMEBUFFER_COMPLETE {
panic!("failed to create fbo")
}
// gl.draw_buffer(glow::COLOR_ATTACHMENT0);
// if gl.check_framebuffer_status(glow::FRAMEBUFFER) != glow::FRAMEBUFFER_COMPLETE {
// panic!("failed to create fbo")
// }
let fullscreen_fbo = [
-1.0f32, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0,

View file

@ -1,7 +1,7 @@
use std::sync::mpsc::Receiver;
use std::sync::Arc;
use glfw::{Context, Glfw, Window, WindowEvent};
use glfw::{fail_on_errors, Context, Glfw, GlfwReceiver, PWindow, Window, WindowEvent};
use glow::HasContext;
use librashader_common::{GetSize, Size, Viewport};
@ -14,13 +14,13 @@ const TITLE: &str = "librashader OpenGL 4.6";
pub fn setup() -> (
Glfw,
Window,
Receiver<(f64, WindowEvent)>,
PWindow,
GlfwReceiver<(f64, WindowEvent)>,
glow::Program,
glow::VertexArray,
Arc<glow::Context>,
) {
let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
let mut glfw = glfw::init(fail_on_errors!()).unwrap();
glfw.window_hint(glfw::WindowHint::ContextVersion(4, 6));
glfw.window_hint(glfw::WindowHint::OpenGlProfile(
glfw::OpenGlProfileHint::Core,
@ -155,8 +155,8 @@ void main()
pub fn do_loop(
gl: &Arc<glow::Context>,
mut glfw: Glfw,
mut window: Window,
events: Receiver<(f64, WindowEvent)>,
mut window: PWindow,
events: GlfwReceiver<(f64, WindowEvent)>,
triangle_program: glow::Program,
triangle_vao: glow::VertexArray,
filter: &mut FilterChainGL,

View file

@ -11,17 +11,17 @@ fn triangle_gl() {
unsafe {
let mut filter = FilterChainGL::load_from_path(
// "../test/basic.slangp",
"../test/shaders_slang/test/feedback.slangp",
"../test/shaders_slang/crt/crt-royale.slangp",
Arc::clone(&context),
Some(&FilterChainOptionsGL {
glsl_version: 0,
use_dsa: false,
force_no_mipmaps: false,
disable_cache: false,
disable_cache: true,
}),
)
// FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None)
.unwrap();
.expect("Failed to load filter chain");
hello_triangle::gl3::do_loop(&context, glfw, window, events, shader, vao, &mut filter);
}
}
@ -35,7 +35,7 @@ fn triangle_gl46() {
// "../test/slang-shaders/test/history.slangp",
// "../test/basic.slangp",
// "../test/shaders_slang/crt/crt-royale.slangp",
"../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
"../test/shaders_slang/crt/crt-royale.slangp",
Arc::clone(&context),
Some(&FilterChainOptionsGL {
glsl_version: 330,