From b017127b9de5542795bc2a51a369dae277ccb236 Mon Sep 17 00:00:00 2001 From: chyyran Date: Mon, 21 Nov 2022 17:44:38 -0500 Subject: [PATCH] gl: use explicit error type --- librashader-common/src/image.rs | 2 + librashader-preprocess/Cargo.toml | 2 +- librashader-runtime-gl/Cargo.toml | 11 +++--- librashader-runtime-gl/src/error.rs | 26 +++++++++++++ librashader-runtime-gl/src/filter_chain.rs | 41 ++++++++++++-------- librashader-runtime-gl/src/filter_pass.rs | 4 +- librashader-runtime-gl/src/framebuffer.rs | 25 +++++++----- librashader-runtime-gl/src/hello_triangle.rs | 3 +- librashader-runtime-gl/src/lib.rs | 13 +------ 9 files changed, 79 insertions(+), 48 deletions(-) create mode 100644 librashader-runtime-gl/src/error.rs diff --git a/librashader-common/src/image.rs b/librashader-common/src/image.rs index 9a7b8d1..c30f3de 100644 --- a/librashader-common/src/image.rs +++ b/librashader-common/src/image.rs @@ -20,3 +20,5 @@ impl Image { }) } } + +pub use image::ImageError; \ No newline at end of file diff --git a/librashader-preprocess/Cargo.toml b/librashader-preprocess/Cargo.toml index 19d20bb..f5d8c16 100644 --- a/librashader-preprocess/Cargo.toml +++ b/librashader-preprocess/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] thiserror = "1.0.37" nom = "7.1.1" -"librashader-common" = { path = "../librashader-common" } +librashader-common = { path = "../librashader-common" } [features] default = [ "line_directives" ] diff --git a/librashader-runtime-gl/Cargo.toml b/librashader-runtime-gl/Cargo.toml index a57935e..be8ac5a 100644 --- a/librashader-runtime-gl/Cargo.toml +++ b/librashader-runtime-gl/Cargo.toml @@ -6,12 +6,13 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -"librashader-common" = { path = "../librashader-common", features = ["opengl"] } -"librashader-presets" = { path = "../librashader-presets" } -"librashader-preprocess" = { path = "../librashader-preprocess" } -"librashader-reflect" = { path = "../librashader-reflect" } +librashader-common = { path = "../librashader-common", features = ["opengl"] } +librashader-presets = { path = "../librashader-presets" } +librashader-preprocess = { path = "../librashader-preprocess" } +librashader-reflect = { path = "../librashader-reflect" } spirv_cross = "0.23.1" rustc-hash = "1.1.0" gl = "0.14.0" glfw = "0.47.0" -bytemuck = "1.12.3" \ No newline at end of file +bytemuck = "1.12.3" +thiserror = "1.0.37" \ No newline at end of file diff --git a/librashader-runtime-gl/src/error.rs b/librashader-runtime-gl/src/error.rs new file mode 100644 index 0000000..8211f52 --- /dev/null +++ b/librashader-runtime-gl/src/error.rs @@ -0,0 +1,26 @@ +use gl::types::GLenum; +use librashader_common::image; +use librashader_preprocess::PreprocessError; +use librashader_presets::ParsePresetError; +use librashader_reflect::error::{ShaderCompileError, ShaderReflectError}; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum FilterChainError { + #[error("fbo initialization error")] + FramebufferInit(GLenum), + #[error("SPIRV reflection error")] + SpirvCrossReflectError(#[from] spirv_cross::ErrorCode), + #[error("shader preset parse error")] + ShaderPresetError(#[from] ParsePresetError), + #[error("shader preprocess error")] + ShaderPreprocessError(#[from] PreprocessError), + #[error("shader compile error")] + ShaderCompileError(#[from] ShaderCompileError), + #[error("shader reflect error")] + ShaderReflectError(#[from] ShaderReflectError), + #[error("lut loading error")] + LutLoadError(#[from] image::ImageError) +} + +pub type Result = std::result::Result; \ No newline at end of file diff --git a/librashader-runtime-gl/src/filter_chain.rs b/librashader-runtime-gl/src/filter_chain.rs index b5368e5..dba6b86 100644 --- a/librashader-runtime-gl/src/filter_chain.rs +++ b/librashader-runtime-gl/src/filter_chain.rs @@ -5,6 +5,8 @@ use crate::quad_render::DrawQuad; use crate::render_target::RenderTarget; use crate::util; use crate::util::{InlineRingBuffer, Texture}; +use crate::error::{FilterChainError, Result}; + use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint}; use librashader_common::image::Image; use librashader_common::{FilterMode, Size, WrapMode}; @@ -32,7 +34,7 @@ pub struct FilterChain { } pub struct FilterCommon { - semantics: ReflectSemantics, + // semantics: ReflectSemantics, pub(crate) preset: ShaderPreset, pub(crate) luts: FxHashMap, pub output_textures: Box<[Texture]>, @@ -129,7 +131,7 @@ type ShaderPassMeta<'a> = ( impl FilterChain { /// Load a filter chain from a pre-parsed `ShaderPreset`. - pub fn load_from_preset(preset: ShaderPreset) -> Result> { + pub fn load_from_preset(preset: ShaderPreset) -> Result { let (passes, semantics) = FilterChain::load_preset(&preset)?; // initialize passes @@ -174,7 +176,8 @@ impl FilterChain { history_framebuffers, filter_vao, common: FilterCommon { - semantics, + // we don't need the reflect semantics once all locations have been bound per pass. + // semantics, preset, luts, output_textures: output_textures.into_boxed_slice(), @@ -186,7 +189,7 @@ impl FilterChain { } /// Load the shader preset at the given path into a filter chain. - pub fn load_from_path(path: impl AsRef) -> Result> { + pub fn load_from_path(path: impl AsRef) -> Result { // load passes from preset let preset = ShaderPreset::try_parse(path)?; Self::load_from_preset(preset) @@ -194,7 +197,7 @@ impl FilterChain { fn load_preset( preset: &ShaderPreset, - ) -> Result<(Vec, ReflectSemantics), Box> { + ) -> Result<(Vec, ReflectSemantics)> { let mut uniform_semantics: FxHashMap = Default::default(); let mut texture_semantics: FxHashMap> = Default::default(); @@ -218,10 +221,10 @@ impl FilterChain { }), ); } - Ok::<_, Box>((shader, source, reflect)) + Ok::<_, FilterChainError>((shader, source, reflect)) }) .into_iter() - .collect::)>, _>>()?; + .collect::)>>>()?; for details in &passes { FilterChain::load_pass_semantics( @@ -258,7 +261,7 @@ impl FilterChain { Ok((passes, semantics)) } - fn load_luts(textures: &[TextureConfig]) -> Result, Box> { + fn load_luts(textures: &[TextureConfig]) -> Result> { let mut luts = FxHashMap::default(); for (index, texture) in textures.iter().enumerate() { @@ -363,7 +366,7 @@ impl FilterChain { fn init_passes( passes: Vec, semantics: &ReflectSemantics, - ) -> Result, Box> { + ) -> Result> { let mut filters = Vec::new(); // initialize passes @@ -578,20 +581,22 @@ impl FilterChain { (framebuffers, history_textures.into_boxed_slice()) } - fn push_history(&mut self, input: &GlImage) { + fn push_history(&mut self, input: &GlImage) -> Result<()> { if let Some(mut back) = self.history_framebuffers.pop_back() { if back.size != input.size || (input.format != 0 && input.format != back.format) { eprintln!("[history] resizing"); - back.init(input.size, input.format); + back.init(input.size, input.format)?; } - back.copy_from(input); + back.copy_from(input)?; self.history_framebuffers.push_front(back) } + + Ok(()) } - pub fn frame(&mut self, count: usize, viewport: &Viewport, input: &GlImage, clear: bool) { + pub fn frame(&mut self, count: usize, viewport: &Viewport, input: &GlImage, clear: bool) -> Result<()> { if clear { for framebuffer in &self.history_framebuffers { framebuffer.clear() @@ -599,7 +604,7 @@ impl FilterChain { } if self.passes.is_empty() { - return; + return Ok(()); } unsafe { @@ -650,7 +655,7 @@ impl FilterChain { viewport, &original, &source, - ); + )?; self.feedback_framebuffers[index].scale( pass.config.scaling.clone(), @@ -658,7 +663,7 @@ impl FilterChain { viewport, &original, &source, - ); + )?; } let passes_len = self.passes.len(); @@ -716,10 +721,12 @@ impl FilterChain { std::mem::swap(output, feedback); } - self.push_history(input); + self.push_history(input)?; unsafe { gl::BindFramebuffer(gl::FRAMEBUFFER, 0); gl::BindVertexArray(0); } + + Ok(()) } } diff --git a/librashader-runtime-gl/src/filter_pass.rs b/librashader-runtime-gl/src/filter_pass.rs index aa76161..ed845cb 100644 --- a/librashader-runtime-gl/src/filter_pass.rs +++ b/librashader-runtime-gl/src/filter_pass.rs @@ -252,9 +252,6 @@ impl FilterPass { gl::Disable(gl::FRAMEBUFFER_SRGB); gl::BindFramebuffer(gl::FRAMEBUFFER, 0); } - - // todo: draw image onto fbo - // shader_gl3 1579 } // framecount should be pre-modded @@ -514,6 +511,7 @@ impl FilterPass { MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), }; + // todo: cache parameters. // presets override params let default = self .source diff --git a/librashader-runtime-gl/src/framebuffer.rs b/librashader-runtime-gl/src/framebuffer.rs index 6e4ae12..684be11 100644 --- a/librashader-runtime-gl/src/framebuffer.rs +++ b/librashader-runtime-gl/src/framebuffer.rs @@ -3,6 +3,8 @@ use crate::util::Texture; use gl::types::{GLenum, GLint, GLsizei, GLuint}; use librashader_common::{FilterMode, ShaderFormat, Size, WrapMode}; use librashader_presets::{Scale2D, ScaleType, Scaling}; +use crate::error::FilterChainError; +use crate::error::Result; #[derive(Debug)] pub struct Framebuffer { @@ -77,9 +79,9 @@ impl Framebuffer { viewport: &Viewport, _original: &Texture, source: &Texture, - ) -> Size { + ) -> Result> { if self.is_raw { - return self.size; + return Ok(self.size); } let mut width = 0f32; @@ -130,9 +132,9 @@ impl Framebuffer { } else { format }, - ); + )?; } - size + Ok(size) } pub(crate) fn clear(&self) { @@ -145,9 +147,9 @@ impl Framebuffer { } } - pub(crate) fn copy_from(&mut self, image: &GlImage) { + pub(crate) fn copy_from(&mut self, image: &GlImage) -> Result<()>{ if image.size != self.size || image.format != self.format { - self.init(image.size, image.format); + self.init(image.size, image.format)?; } unsafe { @@ -210,12 +212,13 @@ impl Framebuffer { gl::BindFramebuffer(gl::FRAMEBUFFER, 0); } + + Ok(()) } - // todo: fix panic - pub(crate) fn init(&mut self, mut size: Size, format: impl Into) { + pub(crate) fn init(&mut self, mut size: Size, format: impl Into) -> Result<()> { if self.is_raw { - return; + return Ok(()); } self.format = format.into(); self.size = size; @@ -310,13 +313,15 @@ impl Framebuffer { // self.init = // gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE; } - _ => panic!("failed to complete: {status:x}"), + _ => return Err(FilterChainError::FramebufferInit(status)) } } gl::BindFramebuffer(gl::FRAMEBUFFER, 0); gl::BindTexture(gl::TEXTURE_2D, 0); } + + Ok(()) } } diff --git a/librashader-runtime-gl/src/hello_triangle.rs b/librashader-runtime-gl/src/hello_triangle.rs index e684a9a..5b6a1d4 100644 --- a/librashader-runtime-gl/src/hello_triangle.rs +++ b/librashader-runtime-gl/src/hello_triangle.rs @@ -517,7 +517,8 @@ void main() padded_size: Default::default(), }; - unsafe { filter.frame(framecount, &viewport, &rendered, false) } + filter.frame(framecount, &viewport, &rendered, false) + .unwrap(); unsafe { // texture is done now. diff --git a/librashader-runtime-gl/src/lib.rs b/librashader-runtime-gl/src/lib.rs index a4937b6..a916196 100644 --- a/librashader-runtime-gl/src/lib.rs +++ b/librashader-runtime-gl/src/lib.rs @@ -9,6 +9,7 @@ mod hello_triangle; mod quad_render; mod render_target; mod util; +mod error; pub use filter_chain::FilterChain; pub use framebuffer::Framebuffer; @@ -24,18 +25,8 @@ mod tests { fn triangle() { let (glfw, window, events, shader, vao) = hello_triangle::setup(); let mut filter = - FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale-fake-bloom.slangp") + FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale.slangp") .unwrap(); - - // FilterChain::load("../test/slang-shaders/crt/crt-royale.slangp").unwrap(); - hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter); } - - // #[test] - // fn load_preset() { - // - // load("../test/basic.slangp") - // .unwrap(); - // } }