From e7fe96520ebf073ebad048fb1e0774564836dff7 Mon Sep 17 00:00:00 2001 From: chyyran Date: Tue, 24 Sep 2024 01:59:01 -0400 Subject: [PATCH] rt(gl): ensure framebuffers are bound --- librashader-runtime-gl/src/error.rs | 2 +- .../src/filter_chain/chain.rs | 6 +-- librashader-runtime-gl/src/filter_pass.rs | 10 ++--- librashader-runtime-gl/src/gl/framebuffer.rs | 4 ++ .../src/gl/gl3/framebuffer.rs | 19 ++++++++ .../src/gl/gl46/framebuffer.rs | 12 ++++++ librashader-runtime-gl/src/gl/mod.rs | 7 ++- .../tests/hello_triangle/gl3.rs | 43 ++++++++++--------- .../tests/hello_triangle/gl46.rs | 12 +++--- librashader-runtime-gl/tests/triangle.rs | 8 ++-- 10 files changed, 82 insertions(+), 41 deletions(-) diff --git a/librashader-runtime-gl/src/error.rs b/librashader-runtime-gl/src/error.rs index 49b3ce1..4493eed 100644 --- a/librashader-runtime-gl/src/error.rs +++ b/librashader-runtime-gl/src/error.rs @@ -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), diff --git a/librashader-runtime-gl/src/filter_chain/chain.rs b/librashader-runtime-gl/src/filter_chain/chain.rs index 5e71e3b..84aaf1a 100644 --- a/librashader-runtime-gl/src/filter_chain/chain.rs +++ b/librashader-runtime-gl/src/filter_chain/chain.rs @@ -377,7 +377,7 @@ impl FilterChainImpl { &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 FilterChainImpl { &original, &source, RenderTarget::viewport_with_output(target, viewport), - ); + )?; } pass.draw( @@ -421,7 +421,7 @@ impl FilterChainImpl { &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); diff --git a/librashader-runtime-gl/src/filter_pass.rs b/librashader-runtime-gl/src/filter_pass.rs index 3dee311..77dbef1 100644 --- a/librashader-runtime-gl/src/filter_pass.rs +++ b/librashader-runtime-gl/src/filter_pass.rs @@ -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 FilterPass { original: &InputTexture, source: &InputTexture, output: RenderTarget, - ) { + ) -> error::Result<()> { let framebuffer = output.output; if self.config.mipmap_input && !parent.disable_mipmaps { @@ -94,9 +94,7 @@ impl FilterPass { } unsafe { - parent - .context - .bind_framebuffer(glow::FRAMEBUFFER, Some(framebuffer.fbo)); + framebuffer.bind::()?; parent.context.use_program(Some(self.program)); } @@ -154,6 +152,8 @@ impl FilterPass { parent.context.disable(glow::FRAMEBUFFER_SRGB); parent.context.bind_framebuffer(glow::FRAMEBUFFER, None); } + + Ok(()) } } diff --git a/librashader-runtime-gl/src/gl/framebuffer.rs b/librashader-runtime-gl/src/gl/framebuffer.rs index 6095135..4a67c19 100644 --- a/librashader-runtime-gl/src/gl/framebuffer.rs +++ b/librashader-runtime-gl/src/gl/framebuffer.rs @@ -87,6 +87,10 @@ impl GLFramebuffer { wrap_mode, } } + + pub(crate) fn bind(&self) -> Result<()> { + T::bind(self) + } } /// A state-checked wrapper around a raw framebuffer, used exclusively for output images. diff --git a/librashader-runtime-gl/src/gl/gl3/framebuffer.rs b/librashader-runtime-gl/src/gl/gl3/framebuffer.rs index d78237c..6d44955 100644 --- a/librashader-runtime-gl/src/gl/gl3/framebuffer.rs +++ b/librashader-runtime-gl/src/gl/gl3/framebuffer.rs @@ -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(()) + } } diff --git a/librashader-runtime-gl/src/gl/gl46/framebuffer.rs b/librashader-runtime-gl/src/gl/gl46/framebuffer.rs index f3d69da..080360a 100644 --- a/librashader-runtime-gl/src/gl/gl46/framebuffer.rs +++ b/librashader-runtime-gl/src/gl/gl46/framebuffer.rs @@ -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(()) + } } diff --git a/librashader-runtime-gl/src/gl/mod.rs b/librashader-runtime-gl/src/gl/mod.rs index cded543..c339685 100644 --- a/librashader-runtime-gl/src/gl/mod.rs +++ b/librashader-runtime-gl/src/gl/mod.rs @@ -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(fb: &GLFramebuffer); fn copy_from(fb: &mut GLFramebuffer, image: &GLImage) -> Result<()>; fn init(fb: &mut GLFramebuffer, size: Size, format: impl Into) -> Result<()>; + fn bind(fb: &GLFramebuffer) -> Result<()>; } pub(crate) trait BindTexture { diff --git a/librashader-runtime-gl/tests/hello_triangle/gl3.rs b/librashader-runtime-gl/tests/hello_triangle/gl3.rs index d170004..cb58f77 100644 --- a/librashader-runtime-gl/tests/hello_triangle/gl3.rs +++ b/librashader-runtime-gl/tests/hello_triangle/gl3.rs @@ -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, ) { - 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, 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, diff --git a/librashader-runtime-gl/tests/hello_triangle/gl46.rs b/librashader-runtime-gl/tests/hello_triangle/gl46.rs index 875e66e..303e271 100644 --- a/librashader-runtime-gl/tests/hello_triangle/gl46.rs +++ b/librashader-runtime-gl/tests/hello_triangle/gl46.rs @@ -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, ) { - 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, 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, diff --git a/librashader-runtime-gl/tests/triangle.rs b/librashader-runtime-gl/tests/triangle.rs index 7885c70..a7b7236 100644 --- a/librashader-runtime-gl/tests/triangle.rs +++ b/librashader-runtime-gl/tests/triangle.rs @@ -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,