gl: use explicit error type

This commit is contained in:
chyyran 2022-11-21 17:44:38 -05:00
parent 86ad32ff0a
commit b017127b9d
9 changed files with 79 additions and 48 deletions

View file

@ -20,3 +20,5 @@ impl Image {
})
}
}
pub use image::ImageError;

View file

@ -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" ]

View file

@ -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"
thiserror = "1.0.37"

View file

@ -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<T> = std::result::Result<T, FilterChainError>;

View file

@ -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<usize, Texture>,
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<FilterChain, Box<dyn Error>> {
pub fn load_from_preset(preset: ShaderPreset) -> Result<FilterChain> {
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<Path>) -> Result<FilterChain, Box<dyn Error>> {
pub fn load_from_path(path: impl AsRef<Path>) -> Result<FilterChain> {
// 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<ShaderPassMeta>, ReflectSemantics), Box<dyn Error>> {
) -> Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
Default::default();
@ -218,10 +221,10 @@ impl FilterChain {
}),
);
}
Ok::<_, Box<dyn Error>>((shader, source, reflect))
Ok::<_, FilterChainError>((shader, source, reflect))
})
.into_iter()
.collect::<Result<Vec<(&ShaderPassConfig, ShaderSource, CompilerBackend<_>)>, _>>()?;
.collect::<Result<Vec<(&ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>()?;
for details in &passes {
FilterChain::load_pass_semantics(
@ -258,7 +261,7 @@ impl FilterChain {
Ok((passes, semantics))
}
fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>, Box<dyn Error>> {
fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>> {
let mut luts = FxHashMap::default();
for (index, texture) in textures.iter().enumerate() {
@ -363,7 +366,7 @@ impl FilterChain {
fn init_passes(
passes: Vec<ShaderPassMeta>,
semantics: &ReflectSemantics,
) -> Result<Box<[FilterPass]>, Box<dyn Error>> {
) -> Result<Box<[FilterPass]>> {
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(())
}
}

View file

@ -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

View file

@ -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<u32> {
) -> Result<Size<u32>> {
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<u32>, format: impl Into<GLenum>) {
pub(crate) fn init(&mut self, mut size: Size<u32>, format: impl Into<GLenum>) -> 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(())
}
}

View file

@ -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.

View file

@ -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();
// }
}