From 7b2721aa19e0a0d4a643fd79aa9bb809fd9ca136 Mon Sep 17 00:00:00 2001 From: chyyran Date: Mon, 28 Nov 2022 18:34:37 -0500 Subject: [PATCH] gl: move quad drawing into filterchain --- librashader-runtime-gl/src/filter_chain.rs | 35 +++++++-------- librashader-runtime-gl/src/filter_pass.rs | 29 ------------- librashader-runtime-gl/src/framebuffer.rs | 4 +- librashader-runtime-gl/src/lib.rs | 2 +- librashader-runtime-gl/src/quad_render.rs | 50 ++++++++++++++++++++-- 5 files changed, 67 insertions(+), 53 deletions(-) diff --git a/librashader-runtime-gl/src/filter_chain.rs b/librashader-runtime-gl/src/filter_chain.rs index 1fec799..e6971e0 100644 --- a/librashader-runtime-gl/src/filter_chain.rs +++ b/librashader-runtime-gl/src/filter_chain.rs @@ -29,7 +29,7 @@ use crate::texture::Texture; pub struct FilterChain { passes: Box<[FilterPass]>, common: FilterCommon, - filter_vao: GLuint, + pub(crate) draw_quad: DrawQuad, output_framebuffers: Box<[Framebuffer]>, feedback_framebuffers: Box<[Framebuffer]>, history_framebuffers: VecDeque, @@ -43,7 +43,6 @@ pub struct FilterCommon { pub output_textures: Box<[Texture]>, pub feedback_textures: Box<[Texture]>, pub history_textures: Box<[Texture]>, - pub(crate) draw_quad: DrawQuad, } pub struct FilterMutable { @@ -174,20 +173,15 @@ impl FilterChain { let (history_framebuffers, history_textures) = FilterChain::init_history(&filters, default_filter, default_wrap); - // create VBO objects + // create vertex objects let draw_quad = DrawQuad::new(); - let mut filter_vao = 0; - unsafe { - gl::GenVertexArrays(1, &mut filter_vao); - } - Ok(FilterChain { passes: filters, output_framebuffers: output_framebuffers.into_boxed_slice(), feedback_framebuffers: feedback_framebuffers.into_boxed_slice(), history_framebuffers, - filter_vao, + draw_quad, common: FilterCommon { config: FilterMutable { passes_enabled: preset.shader_count as usize, @@ -199,7 +193,6 @@ impl FilterChain { output_textures: output_textures.into_boxed_slice(), feedback_textures: feedback_textures.into_boxed_slice(), history_textures, - draw_quad, }, }) } @@ -279,6 +272,11 @@ impl FilterChain { fn load_luts(textures: &[TextureConfig]) -> Result> { let mut luts = FxHashMap::default(); + let pixel_unpack = unsafe { + let mut binding = 0; + gl::GetIntegerv(gl::PIXEL_UNPACK_BUFFER_BINDING, &mut binding); + binding + }; for (index, texture) in textures.iter().enumerate() { let image = Image::load(&texture.path)?; @@ -338,6 +336,10 @@ impl FilterChain { }, ); } + + unsafe { + gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, pixel_unpack as GLuint); + }; Ok(luts) } @@ -593,11 +595,9 @@ impl FilterChain { return Ok(()); } - unsafe { - // do not need to rebind FBO 0 here since first `draw` will - // bind automatically. - gl::BindVertexArray(self.filter_vao); - } + // do not need to rebind FBO 0 here since first `draw` will + // bind automatically. + self.draw_quad.bind_vao(); let filter = passes[0].config.filter; let wrap_mode = passes[0].config.wrap_mode; @@ -710,10 +710,7 @@ impl FilterChain { self.push_history(input)?; - // pass.draw should return framebuffer bound to 0. - unsafe { - gl::BindVertexArray(0); - } + self.draw_quad.unbind_vao(); Ok(()) } diff --git a/librashader-runtime-gl/src/filter_pass.rs b/librashader-runtime-gl/src/filter_pass.rs index 40dd89f..46762df 100644 --- a/librashader-runtime-gl/src/filter_pass.rs +++ b/librashader-runtime-gl/src/filter_pass.rs @@ -204,36 +204,7 @@ impl FilterPass { gl::Disable(gl::BLEND); gl::Disable(gl::DEPTH_TEST); - gl::EnableVertexAttribArray(0); - gl::EnableVertexAttribArray(1); - - gl::BindBuffer(gl::ARRAY_BUFFER, parent.draw_quad.vbo); - - // the provided pointers are of OpenGL provenance with respect to the buffer bound to quad_vbo, - // and not a known provenance to the Rust abstract machine, therefore we give it invalid pointers. - // that are inexpressible in Rust - gl::VertexAttribPointer( - 0, - 2, - gl::FLOAT, - gl::FALSE, - (4 * std::mem::size_of::()) as GLsizei, - std::ptr::invalid(0), - ); - gl::VertexAttribPointer( - 1, - 2, - gl::FLOAT, - gl::FALSE, - (4 * std::mem::size_of::()) as GLsizei, - std::ptr::invalid(2 * std::mem::size_of::()), - ); gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4); - - gl::BindBuffer(gl::ARRAY_BUFFER, 0); - gl::DisableVertexAttribArray(0); - gl::DisableVertexAttribArray(1); - gl::Disable(gl::FRAMEBUFFER_SRGB); gl::BindFramebuffer(gl::FRAMEBUFFER, 0); } diff --git a/librashader-runtime-gl/src/framebuffer.rs b/librashader-runtime-gl/src/framebuffer.rs index 28b55bd..8cfa69d 100644 --- a/librashader-runtime-gl/src/framebuffer.rs +++ b/librashader-runtime-gl/src/framebuffer.rs @@ -171,6 +171,7 @@ impl Framebuffer { self.image, 0, ); + gl::ReadBuffer(gl::COLOR_ATTACHMENT0); gl::DrawBuffer(gl::COLOR_ATTACHMENT1); gl::BlitFramebuffer( 0, @@ -264,6 +265,7 @@ impl Framebuffer { size.width as GLsizei, size.height as GLsizei, ); + gl::FramebufferTexture2D( gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, @@ -287,7 +289,7 @@ impl Framebuffer { ); gl::DeleteTextures(1, &self.image); gl::GenTextures(1, &mut self.image); - gl::BindTexture(1, self.image); + gl::BindTexture(gl::TEXTURE_2D, self.image); self.levels = util::calc_miplevel(size); if self.levels > self.max_levels { diff --git a/librashader-runtime-gl/src/lib.rs b/librashader-runtime-gl/src/lib.rs index fdfa43e..669e0f7 100644 --- a/librashader-runtime-gl/src/lib.rs +++ b/librashader-runtime-gl/src/lib.rs @@ -31,7 +31,7 @@ mod tests { fn triangle_gl() { let (glfw, window, events, shader, vao) = hello_triangle::setup(); let mut filter = - FilterChain::load_from_path("../test/slang-shaders/vhs/VHSPro.slangp", None) + FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale.slangp", None) .unwrap(); hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter); } diff --git a/librashader-runtime-gl/src/quad_render.rs b/librashader-runtime-gl/src/quad_render.rs index 272fd97..0018ccc 100644 --- a/librashader-runtime-gl/src/quad_render.rs +++ b/librashader-runtime-gl/src/quad_render.rs @@ -1,4 +1,4 @@ -use gl::types::{GLsizeiptr, GLuint}; +use gl::types::{GLsizei, GLsizeiptr, GLuint}; #[rustfmt::skip] static QUAD_VBO_DATA: &[f32; 16] = &[ @@ -9,12 +9,15 @@ static QUAD_VBO_DATA: &[f32; 16] = &[ ]; pub struct DrawQuad { - pub vbo: GLuint, + vbo: GLuint, + vao: GLuint, } impl DrawQuad { pub fn new() -> DrawQuad { let mut vbo = 0; + let mut vao = 0; + unsafe { gl::GenBuffers(1, &mut vbo); gl::BindBuffer(gl::ARRAY_BUFFER, vbo); @@ -25,8 +28,49 @@ impl DrawQuad { gl::STATIC_DRAW, ); gl::BindBuffer(gl::ARRAY_BUFFER, 0); + gl::GenVertexArrays(1, &mut vao); } - DrawQuad { vbo } + + DrawQuad { vbo, vao } + } + + pub fn bind_vao(&self) { + unsafe { + gl::BindVertexArray(self.vao); + gl::EnableVertexAttribArray(0); + gl::EnableVertexAttribArray(1); + + gl::BindBuffer(gl::ARRAY_BUFFER, self.vbo); + + // the provided pointers are of OpenGL provenance with respect to the buffer bound to quad_vbo, + // and not a known provenance to the Rust abstract machine, therefore we give it invalid pointers. + // that are inexpressible in Rust + gl::VertexAttribPointer( + 0, + 2, + gl::FLOAT, + gl::FALSE, + (4 * std::mem::size_of::()) as GLsizei, + std::ptr::invalid(0), + ); + gl::VertexAttribPointer( + 1, + 2, + gl::FLOAT, + gl::FALSE, + (4 * std::mem::size_of::()) as GLsizei, + std::ptr::invalid(2 * std::mem::size_of::()), + ); + } + } + + pub fn unbind_vao(&self) { + unsafe { + gl::BindVertexArray(0); + gl::BindBuffer(gl::ARRAY_BUFFER, 0); + gl::DisableVertexAttribArray(0); + gl::DisableVertexAttribArray(1); + } } }