gl: use explicit error type
This commit is contained in:
parent
86ad32ff0a
commit
b017127b9d
|
@ -20,3 +20,5 @@ impl Image {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use image::ImageError;
|
|
@ -8,7 +8,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
thiserror = "1.0.37"
|
thiserror = "1.0.37"
|
||||||
nom = "7.1.1"
|
nom = "7.1.1"
|
||||||
"librashader-common" = { path = "../librashader-common" }
|
librashader-common = { path = "../librashader-common" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "line_directives" ]
|
default = [ "line_directives" ]
|
||||||
|
|
|
@ -6,12 +6,13 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
"librashader-common" = { path = "../librashader-common", features = ["opengl"] }
|
librashader-common = { path = "../librashader-common", features = ["opengl"] }
|
||||||
"librashader-presets" = { path = "../librashader-presets" }
|
librashader-presets = { path = "../librashader-presets" }
|
||||||
"librashader-preprocess" = { path = "../librashader-preprocess" }
|
librashader-preprocess = { path = "../librashader-preprocess" }
|
||||||
"librashader-reflect" = { path = "../librashader-reflect" }
|
librashader-reflect = { path = "../librashader-reflect" }
|
||||||
spirv_cross = "0.23.1"
|
spirv_cross = "0.23.1"
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
gl = "0.14.0"
|
gl = "0.14.0"
|
||||||
glfw = "0.47.0"
|
glfw = "0.47.0"
|
||||||
bytemuck = "1.12.3"
|
bytemuck = "1.12.3"
|
||||||
|
thiserror = "1.0.37"
|
26
librashader-runtime-gl/src/error.rs
Normal file
26
librashader-runtime-gl/src/error.rs
Normal 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>;
|
|
@ -5,6 +5,8 @@ use crate::quad_render::DrawQuad;
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::util::{InlineRingBuffer, Texture};
|
use crate::util::{InlineRingBuffer, Texture};
|
||||||
|
use crate::error::{FilterChainError, Result};
|
||||||
|
|
||||||
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
|
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use librashader_common::{FilterMode, Size, WrapMode};
|
use librashader_common::{FilterMode, Size, WrapMode};
|
||||||
|
@ -32,7 +34,7 @@ pub struct FilterChain {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FilterCommon {
|
pub struct FilterCommon {
|
||||||
semantics: ReflectSemantics,
|
// semantics: ReflectSemantics,
|
||||||
pub(crate) preset: ShaderPreset,
|
pub(crate) preset: ShaderPreset,
|
||||||
pub(crate) luts: FxHashMap<usize, Texture>,
|
pub(crate) luts: FxHashMap<usize, Texture>,
|
||||||
pub output_textures: Box<[Texture]>,
|
pub output_textures: Box<[Texture]>,
|
||||||
|
@ -129,7 +131,7 @@ type ShaderPassMeta<'a> = (
|
||||||
|
|
||||||
impl FilterChain {
|
impl FilterChain {
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// 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)?;
|
let (passes, semantics) = FilterChain::load_preset(&preset)?;
|
||||||
|
|
||||||
// initialize passes
|
// initialize passes
|
||||||
|
@ -174,7 +176,8 @@ impl FilterChain {
|
||||||
history_framebuffers,
|
history_framebuffers,
|
||||||
filter_vao,
|
filter_vao,
|
||||||
common: FilterCommon {
|
common: FilterCommon {
|
||||||
semantics,
|
// we don't need the reflect semantics once all locations have been bound per pass.
|
||||||
|
// semantics,
|
||||||
preset,
|
preset,
|
||||||
luts,
|
luts,
|
||||||
output_textures: output_textures.into_boxed_slice(),
|
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.
|
/// 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
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(preset)
|
Self::load_from_preset(preset)
|
||||||
|
@ -194,7 +197,7 @@ impl FilterChain {
|
||||||
|
|
||||||
fn load_preset(
|
fn load_preset(
|
||||||
preset: &ShaderPreset,
|
preset: &ShaderPreset,
|
||||||
) -> Result<(Vec<ShaderPassMeta>, ReflectSemantics), Box<dyn Error>> {
|
) -> Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
|
||||||
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
||||||
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
|
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
|
||||||
Default::default();
|
Default::default();
|
||||||
|
@ -218,10 +221,10 @@ impl FilterChain {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok::<_, Box<dyn Error>>((shader, source, reflect))
|
Ok::<_, FilterChainError>((shader, source, reflect))
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<Result<Vec<(&ShaderPassConfig, ShaderSource, CompilerBackend<_>)>, _>>()?;
|
.collect::<Result<Vec<(&ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>()?;
|
||||||
|
|
||||||
for details in &passes {
|
for details in &passes {
|
||||||
FilterChain::load_pass_semantics(
|
FilterChain::load_pass_semantics(
|
||||||
|
@ -258,7 +261,7 @@ impl FilterChain {
|
||||||
Ok((passes, semantics))
|
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();
|
let mut luts = FxHashMap::default();
|
||||||
|
|
||||||
for (index, texture) in textures.iter().enumerate() {
|
for (index, texture) in textures.iter().enumerate() {
|
||||||
|
@ -363,7 +366,7 @@ impl FilterChain {
|
||||||
fn init_passes(
|
fn init_passes(
|
||||||
passes: Vec<ShaderPassMeta>,
|
passes: Vec<ShaderPassMeta>,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
) -> Result<Box<[FilterPass]>, Box<dyn Error>> {
|
) -> Result<Box<[FilterPass]>> {
|
||||||
let mut filters = Vec::new();
|
let mut filters = Vec::new();
|
||||||
|
|
||||||
// initialize passes
|
// initialize passes
|
||||||
|
@ -578,20 +581,22 @@ impl FilterChain {
|
||||||
(framebuffers, history_textures.into_boxed_slice())
|
(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 let Some(mut back) = self.history_framebuffers.pop_back() {
|
||||||
if back.size != input.size || (input.format != 0 && input.format != back.format) {
|
if back.size != input.size || (input.format != 0 && input.format != back.format) {
|
||||||
eprintln!("[history] resizing");
|
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)
|
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 {
|
if clear {
|
||||||
for framebuffer in &self.history_framebuffers {
|
for framebuffer in &self.history_framebuffers {
|
||||||
framebuffer.clear()
|
framebuffer.clear()
|
||||||
|
@ -599,7 +604,7 @@ impl FilterChain {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.passes.is_empty() {
|
if self.passes.is_empty() {
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -650,7 +655,7 @@ impl FilterChain {
|
||||||
viewport,
|
viewport,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
);
|
)?;
|
||||||
|
|
||||||
self.feedback_framebuffers[index].scale(
|
self.feedback_framebuffers[index].scale(
|
||||||
pass.config.scaling.clone(),
|
pass.config.scaling.clone(),
|
||||||
|
@ -658,7 +663,7 @@ impl FilterChain {
|
||||||
viewport,
|
viewport,
|
||||||
&original,
|
&original,
|
||||||
&source,
|
&source,
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let passes_len = self.passes.len();
|
let passes_len = self.passes.len();
|
||||||
|
@ -716,10 +721,12 @@ impl FilterChain {
|
||||||
std::mem::swap(output, feedback);
|
std::mem::swap(output, feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.push_history(input);
|
self.push_history(input)?;
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||||
gl::BindVertexArray(0);
|
gl::BindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,9 +252,6 @@ impl FilterPass {
|
||||||
gl::Disable(gl::FRAMEBUFFER_SRGB);
|
gl::Disable(gl::FRAMEBUFFER_SRGB);
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: draw image onto fbo
|
|
||||||
// shader_gl3 1579
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// framecount should be pre-modded
|
// framecount should be pre-modded
|
||||||
|
@ -514,6 +511,7 @@ impl FilterPass {
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset),
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// todo: cache parameters.
|
||||||
// presets override params
|
// presets override params
|
||||||
let default = self
|
let default = self
|
||||||
.source
|
.source
|
||||||
|
|
|
@ -3,6 +3,8 @@ use crate::util::Texture;
|
||||||
use gl::types::{GLenum, GLint, GLsizei, GLuint};
|
use gl::types::{GLenum, GLint, GLsizei, GLuint};
|
||||||
use librashader_common::{FilterMode, ShaderFormat, Size, WrapMode};
|
use librashader_common::{FilterMode, ShaderFormat, Size, WrapMode};
|
||||||
use librashader_presets::{Scale2D, ScaleType, Scaling};
|
use librashader_presets::{Scale2D, ScaleType, Scaling};
|
||||||
|
use crate::error::FilterChainError;
|
||||||
|
use crate::error::Result;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Framebuffer {
|
pub struct Framebuffer {
|
||||||
|
@ -77,9 +79,9 @@ impl Framebuffer {
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
_original: &Texture,
|
_original: &Texture,
|
||||||
source: &Texture,
|
source: &Texture,
|
||||||
) -> Size<u32> {
|
) -> Result<Size<u32>> {
|
||||||
if self.is_raw {
|
if self.is_raw {
|
||||||
return self.size;
|
return Ok(self.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut width = 0f32;
|
let mut width = 0f32;
|
||||||
|
@ -130,9 +132,9 @@ impl Framebuffer {
|
||||||
} else {
|
} else {
|
||||||
format
|
format
|
||||||
},
|
},
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
size
|
Ok(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clear(&self) {
|
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 {
|
if image.size != self.size || image.format != self.format {
|
||||||
self.init(image.size, image.format);
|
self.init(image.size, image.format)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -210,12 +212,13 @@ impl Framebuffer {
|
||||||
|
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: fix panic
|
pub(crate) fn init(&mut self, mut size: Size<u32>, format: impl Into<GLenum>) -> Result<()> {
|
||||||
pub(crate) fn init(&mut self, mut size: Size<u32>, format: impl Into<GLenum>) {
|
|
||||||
if self.is_raw {
|
if self.is_raw {
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
self.format = format.into();
|
self.format = format.into();
|
||||||
self.size = size;
|
self.size = size;
|
||||||
|
@ -310,13 +313,15 @@ impl Framebuffer {
|
||||||
// self.init =
|
// self.init =
|
||||||
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
|
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
|
||||||
}
|
}
|
||||||
_ => panic!("failed to complete: {status:x}"),
|
_ => return Err(FilterChainError::FramebufferInit(status))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||||
gl::BindTexture(gl::TEXTURE_2D, 0);
|
gl::BindTexture(gl::TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -517,7 +517,8 @@ void main()
|
||||||
padded_size: Default::default(),
|
padded_size: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe { filter.frame(framecount, &viewport, &rendered, false) }
|
filter.frame(framecount, &viewport, &rendered, false)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// texture is done now.
|
// texture is done now.
|
||||||
|
|
|
@ -9,6 +9,7 @@ mod hello_triangle;
|
||||||
mod quad_render;
|
mod quad_render;
|
||||||
mod render_target;
|
mod render_target;
|
||||||
mod util;
|
mod util;
|
||||||
|
mod error;
|
||||||
|
|
||||||
pub use filter_chain::FilterChain;
|
pub use filter_chain::FilterChain;
|
||||||
pub use framebuffer::Framebuffer;
|
pub use framebuffer::Framebuffer;
|
||||||
|
@ -24,18 +25,8 @@ mod tests {
|
||||||
fn triangle() {
|
fn triangle() {
|
||||||
let (glfw, window, events, shader, vao) = hello_triangle::setup();
|
let (glfw, window, events, shader, vao) = hello_triangle::setup();
|
||||||
let mut filter =
|
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();
|
.unwrap();
|
||||||
|
|
||||||
// FilterChain::load("../test/slang-shaders/crt/crt-royale.slangp").unwrap();
|
|
||||||
|
|
||||||
hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter);
|
hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn load_preset() {
|
|
||||||
//
|
|
||||||
// load("../test/basic.slangp")
|
|
||||||
// .unwrap();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue