From 4124ae3955c9d6b27ed9e9f337f28303a1742e29 Mon Sep 17 00:00:00 2001 From: chyyran Date: Mon, 21 Nov 2022 02:56:03 -0500 Subject: [PATCH] gl: clean up visibility in some APIs --- librashader-runtime-gl/src/filter_chain.rs | 139 +++++++++---------- librashader-runtime-gl/src/filter_pass.rs | 3 +- librashader-runtime-gl/src/framebuffer.rs | 59 +++++--- librashader-runtime-gl/src/hello_triangle.rs | 3 +- librashader-runtime-gl/src/lib.rs | 8 +- librashader-runtime-gl/src/render_target.rs | 4 +- librashader-runtime-gl/src/util.rs | 24 +--- 7 files changed, 123 insertions(+), 117 deletions(-) diff --git a/librashader-runtime-gl/src/filter_chain.rs b/librashader-runtime-gl/src/filter_chain.rs index 0ea1060..acd897a 100644 --- a/librashader-runtime-gl/src/filter_chain.rs +++ b/librashader-runtime-gl/src/filter_chain.rs @@ -1,15 +1,15 @@ use std::collections::VecDeque; use crate::binding::{UniformBinding, UniformLocation, VariableLocation}; use crate::filter_pass::FilterPass; -use crate::framebuffer::Framebuffer; +use crate::framebuffer::{Framebuffer, GlImage, Size, Viewport}; use crate::render_target::RenderTarget; use crate::util; -use crate::util::{GlImage, InlineRingBuffer, Size, Texture, Viewport}; +use crate::util::{InlineRingBuffer, Texture}; use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint}; use librashader::image::Image; use librashader::{FilterMode, ShaderSource, WrapMode}; use librashader_presets::{ScaleType, ShaderPassConfig, ShaderPreset, TextureConfig}; -use librashader_reflect::back::cross::{GlVersion, GlslangGlslContext}; +use librashader_reflect::back::cross::{GlslangGlslContext, GlVersion}; use librashader_reflect::back::targets::{CompilerBackend, FromCompilation, GLSL}; use librashader_reflect::back::CompileShader; use librashader_reflect::reflect::semantics::{ @@ -131,6 +131,68 @@ type ShaderPassMeta<'a> = ( ); impl FilterChain { + /// Load a filter chain from a pre-parsed `ShaderPreset`. + pub fn load_from_preset(preset: ShaderPreset) -> Result> { + let (passes, semantics) = FilterChain::load_preset(&preset); + + // initialize passes + let filters = FilterChain::init_passes(passes, &semantics)?; + + let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default(); + let default_wrap = filters.first().map(|f| f.config.wrap_mode).unwrap_or_default(); + + // initialize output framebuffers + let mut output_framebuffers = Vec::new(); + output_framebuffers.resize_with(filters.len(), || Framebuffer::new(1)); + let mut output_textures = Vec::new(); + output_textures.resize_with(filters.len(), Texture::default); + + + // initialize feedback framebuffers + let mut feedback_framebuffers = Vec::new(); + feedback_framebuffers.resize_with(filters.len(), || Framebuffer::new(1)); + let mut feedback_textures = Vec::new(); + feedback_textures.resize_with(filters.len(), Texture::default); + + // load luts + let luts = FilterChain::load_luts(&preset.textures)?; + + let (history_framebuffers, history_textures) = + FilterChain::init_history(&filters, default_filter, default_wrap); + + // create VBO 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, + common: FilterCommon { + semantics, + preset, + luts, + output_textures: output_textures.into_boxed_slice(), + feedback_textures: feedback_textures.into_boxed_slice(), + history_textures, + draw_quad, + }, + }) + } + + /// Load the shader preset at the given path into a filter chain. + pub fn load_from_path(path: impl AsRef) -> Result> { + // load passes from preset + let preset = ShaderPreset::try_parse(path)?; + Self::load_from_preset(preset) + } + fn load_preset(preset: &ShaderPreset) -> (Vec, ReflectSemantics) { let mut uniform_semantics: FxHashMap = Default::default(); let mut texture_semantics: FxHashMap> = @@ -300,7 +362,7 @@ impl FilterChain { Ok(luts) } - pub fn init_passes( + fn init_passes( passes: Vec, semantics: &ReflectSemantics, ) -> Result, Box> { @@ -467,7 +529,7 @@ impl FilterChain { Ok(filters.into_boxed_slice()) } - pub fn init_history(filters: &[FilterPass], filter: FilterMode, wrap_mode: WrapMode) -> (VecDeque, Box<[Texture]>) { + fn init_history(filters: &[FilterPass], filter: FilterMode, wrap_mode: WrapMode) -> (VecDeque, Box<[Texture]>) { let mut required_images = 0; for pass in filters { @@ -514,68 +576,7 @@ impl FilterChain { (framebuffers, history_textures.into_boxed_slice()) } - pub fn load(path: impl AsRef) -> Result> { - // load passes from preset - let preset = ShaderPreset::try_parse(path)?; - let (passes, semantics) = FilterChain::load_preset(&preset); - - // initialize passes - let filters = FilterChain::init_passes(passes, &semantics)?; - - let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default(); - let default_wrap = filters.first().map(|f| f.config.wrap_mode).unwrap_or_default(); - - // initialize output framebuffers - let mut output_framebuffers = Vec::new(); - output_framebuffers.resize_with(filters.len(), || Framebuffer::new(1)); - let mut output_textures = Vec::new(); - output_textures.resize_with(filters.len(), Texture::default); - - - // initialize feedback framebuffers - let mut feedback_framebuffers = Vec::new(); - feedback_framebuffers.resize_with(filters.len(), || Framebuffer::new(1)); - let mut feedback_textures = Vec::new(); - feedback_textures.resize_with(filters.len(), Texture::default); - - // load luts - let luts = FilterChain::load_luts(&preset.textures)?; - - let (history_framebuffers, history_textures) = - FilterChain::init_history(&filters, default_filter, default_wrap); - - // create VBO 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, - common: FilterCommon { - semantics, - preset, - luts, - output_textures: output_textures.into_boxed_slice(), - feedback_textures: feedback_textures.into_boxed_slice(), - history_textures, - draw_quad, - }, - }) - } - - pub(crate) fn get_output_texture(&self, index: usize) -> Texture { - let config = &self.passes[index].config; - self.output_framebuffers[index].as_texture(config.filter, config.wrap_mode) - } - - pub fn push_history(&mut self, input: &GlImage) { + fn push_history(&mut self, input: &GlImage) { if let Some(mut back) = self.history_framebuffers.pop_back() { if back.size != input.size @@ -584,9 +585,7 @@ impl FilterChain { back.init(input.size, input.format); } - if back.is_initialized() { - back.copy_from(&input); - } + back.copy_from(&input); self.history_framebuffers.push_front(back) } diff --git a/librashader-runtime-gl/src/filter_pass.rs b/librashader-runtime-gl/src/filter_pass.rs index 8ec56f0..4d65379 100644 --- a/librashader-runtime-gl/src/filter_pass.rs +++ b/librashader-runtime-gl/src/filter_pass.rs @@ -12,8 +12,9 @@ use rustc_hash::FxHashMap; use crate::binding::{UniformBinding, UniformLocation, VariableLocation}; use crate::filter_chain::FilterCommon; +use crate::framebuffer::{Size, Viewport}; use crate::render_target::RenderTarget; -use crate::util::{InlineRingBuffer, RingBuffer, Size, Texture, Viewport}; +use crate::util::{InlineRingBuffer, RingBuffer, Texture}; pub struct FilterPass { pub reflection: ShaderReflection, diff --git a/librashader-runtime-gl/src/framebuffer.rs b/librashader-runtime-gl/src/framebuffer.rs index 1603004..0a357b8 100644 --- a/librashader-runtime-gl/src/framebuffer.rs +++ b/librashader-runtime-gl/src/framebuffer.rs @@ -1,5 +1,5 @@ use crate::util; -use crate::util::{GlImage, Size, Texture, Viewport}; +use crate::util::Texture; use gl::types::{GLenum, GLint, GLsizei, GLuint}; use librashader::{FilterMode, ShaderFormat, WrapMode}; use librashader_presets::{Scale2D, ScaleType, Scaling}; @@ -7,12 +7,12 @@ use librashader_presets::{Scale2D, ScaleType, Scaling}; #[derive(Debug)] pub struct Framebuffer { pub image: GLuint, + pub handle: GLuint, pub size: Size, pub format: GLenum, pub max_levels: u32, pub levels: u32, - pub handle: GLuint, - pub init: bool, + is_raw: bool, } impl Framebuffer { @@ -34,7 +34,7 @@ impl Framebuffer { max_levels, levels: 0, handle: framebuffer, - init: false, + is_raw: false } } @@ -52,11 +52,11 @@ impl Framebuffer { max_levels: miplevels, levels: miplevels, handle, - init: true, + is_raw: true } } - pub fn as_texture(&self, filter: FilterMode, wrap_mode: WrapMode) -> Texture { + pub(crate) fn as_texture(&self, filter: FilterMode, wrap_mode: WrapMode) -> Texture { Texture { image: GlImage { handle: self.image, @@ -70,7 +70,7 @@ impl Framebuffer { } } - pub fn scale( + pub(crate) fn scale( &mut self, scaling: Scale2D, format: ShaderFormat, @@ -78,6 +78,10 @@ impl Framebuffer { _original: &Texture, source: &Texture, ) -> Size { + if self.is_raw { + return self.size; + } + let mut width = 0f32; let mut height = 0f32; @@ -131,11 +135,7 @@ impl Framebuffer { size } - pub(crate) fn is_initialized(&self) -> bool { - self.init - } - - pub fn clear(&self) { + pub(crate) fn clear(&self) { unsafe { gl::BindFramebuffer(gl::FRAMEBUFFER, self.handle); gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); @@ -145,7 +145,7 @@ impl Framebuffer { } } - pub fn copy_from(&mut self, image: &GlImage) { + pub(crate) fn copy_from(&mut self, image: &GlImage) { if image.size != self.size || image.format != self.format { self.init(image.size, image.format); } @@ -190,9 +190,12 @@ impl Framebuffer { gl::BindFramebuffer(gl::FRAMEBUFFER, 0); } } + // todo: fix panic pub(crate) fn init(&mut self, mut size: Size, format: impl Into) { - self.init = false; + if self.is_raw { + return; + } self.format = format.into(); self.size = size; @@ -283,13 +286,11 @@ impl Framebuffer { self.image, 0, ); - self.init = - gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE; + // self.init = + // gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE; } _ => panic!("failed to complete: {status:x}"), } - } else { - self.init = true; } gl::BindFramebuffer(gl::FRAMEBUFFER, 0); @@ -310,3 +311,25 @@ impl Drop for Framebuffer { } } } + +#[derive(Debug, Copy, Clone)] +pub struct Viewport<'a> { + pub x: i32, + pub y: i32, + pub output: &'a Framebuffer, + pub mvp: Option<&'a [f32]>, +} + +#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] +pub struct Size { + pub width: u32, + pub height: u32, +} + +#[derive(Default, Debug, Copy, Clone)] +pub struct GlImage { + pub handle: GLuint, + pub format: GLenum, + pub size: Size, + pub padded_size: Size, +} diff --git a/librashader-runtime-gl/src/hello_triangle.rs b/librashader-runtime-gl/src/hello_triangle.rs index ebebf58..10b8580 100644 --- a/librashader-runtime-gl/src/hello_triangle.rs +++ b/librashader-runtime-gl/src/hello_triangle.rs @@ -7,8 +7,7 @@ use glfw::{Context, Glfw, Window, WindowEvent}; use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint}; use crate::filter_chain::FilterChain; -use crate::framebuffer::Framebuffer; -use crate::util::{GlImage, Size, Viewport}; +use crate::framebuffer::{Framebuffer, GlImage, Size, Viewport}; const WIDTH: u32 = 900; const HEIGHT: u32 = 700; diff --git a/librashader-runtime-gl/src/lib.rs b/librashader-runtime-gl/src/lib.rs index 174ae83..0a6b38a 100644 --- a/librashader-runtime-gl/src/lib.rs +++ b/librashader-runtime-gl/src/lib.rs @@ -10,6 +10,12 @@ mod render_target; mod util; mod quad_render; +pub use filter_chain::FilterChain; +pub use framebuffer::Viewport; +pub use framebuffer::GlImage; +pub use framebuffer::Size; +pub use framebuffer::Framebuffer; + #[cfg(test)] mod tests { use super::*; @@ -18,7 +24,7 @@ mod tests { #[test] fn triangle() { let (glfw, window, events, shader, vao) = hello_triangle::setup(); - let mut filter = FilterChain::load("../test/slang-shaders/crt/crt-royale-fake-bloom.slangp").unwrap(); + let mut filter = FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale-fake-bloom.slangp").unwrap(); // FilterChain::load("../test/slang-shaders/crt/crt-royale.slangp").unwrap(); diff --git a/librashader-runtime-gl/src/render_target.rs b/librashader-runtime-gl/src/render_target.rs index 27c7128..a32d263 100644 --- a/librashader-runtime-gl/src/render_target.rs +++ b/librashader-runtime-gl/src/render_target.rs @@ -1,5 +1,5 @@ -use crate::framebuffer::Framebuffer; -use crate::util::{Texture, Viewport}; +use crate::framebuffer::{Framebuffer, Viewport}; +use crate::util::Texture; #[rustfmt::skip] static DEFAULT_MVP: &[f32] = &[ diff --git a/librashader-runtime-gl/src/util.rs b/librashader-runtime-gl/src/util.rs index 40fda89..8eeadad 100644 --- a/librashader-runtime-gl/src/util.rs +++ b/librashader-runtime-gl/src/util.rs @@ -1,4 +1,4 @@ -use crate::framebuffer::Framebuffer; +use crate::framebuffer::{Framebuffer, GlImage}; use gl::types::{GLenum, GLuint}; use librashader::{FilterMode, WrapMode}; @@ -21,28 +21,6 @@ pub struct Texture { pub wrap_mode: WrapMode, } -#[derive(Debug, Copy, Clone)] -pub struct Viewport<'a> { - pub x: i32, - pub y: i32, - pub output: &'a Framebuffer, - pub mvp: Option<&'a [f32]>, -} - -#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] -pub struct Size { - pub width: u32, - pub height: u32, -} - -#[derive(Default, Debug, Copy, Clone)] -pub struct GlImage { - pub handle: GLuint, - pub format: GLenum, - pub size: Size, - pub padded_size: Size, -} - pub trait RingBuffer { fn current(&self) -> &T; fn current_mut(&mut self) -> &mut T;