gl: clean up filter_chain a little bit

This commit is contained in:
chyyran 2022-11-20 01:09:05 -05:00
parent eb582e396e
commit 23b13ef047
8 changed files with 211 additions and 181 deletions

View file

@ -4,15 +4,14 @@ use nom::branch::alt;
use nom::bytes::complete::{is_not, take_until}; use nom::bytes::complete::{is_not, take_until};
use nom::character::complete::{char, line_ending, multispace1, not_line_ending}; use nom::character::complete::{char, line_ending, multispace1, not_line_ending};
use nom::combinator::{eof, map_res, opt, value}; use nom::combinator::{eof, map_res, value};
use nom::error::{ErrorKind, ParseError}; use nom::error::{ErrorKind, ParseError};
use nom::sequence::{delimited, preceded}; use nom::sequence::delimited;
use nom::{ use nom::{
bytes::complete::tag, character::complete::multispace0, IResult, InputIter, InputLength, bytes::complete::tag, character::complete::multispace0, IResult, InputIter, InputLength,
InputTake, InputTake,
}; };
use nom::multi::many0;
#[derive(Debug)] #[derive(Debug)]
pub struct Token<'a> { pub struct Token<'a> {

View file

@ -1,5 +1,4 @@
use crate::error::ParsePresetError; use crate::error::ParsePresetError;
use std::convert::Infallible;
use std::ops::Mul; use std::ops::Mul;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;

View file

@ -7,9 +7,9 @@ use crate::util::{GlImage, RingBuffer, Size, Texture, Viewport};
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint}; use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
use librashader::image::Image; use librashader::image::Image;
use librashader::{FilterMode, ShaderSource}; use librashader::{FilterMode, ShaderSource};
use librashader_presets::{ShaderPassConfig, ShaderPreset}; use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
use librashader_reflect::back::cross::GlVersion; use librashader_reflect::back::cross::{GlVersion, GlslangGlslContext};
use librashader_reflect::back::targets::{FromCompilation, GLSL}; use librashader_reflect::back::targets::{CompilerBackend, FromCompilation, GLSL};
use librashader_reflect::back::CompileShader; use librashader_reflect::back::CompileShader;
use librashader_reflect::reflect::semantics::{ use librashader_reflect::reflect::semantics::{
MemberOffset, SemanticMap, TextureSemantics, UniformMeta, VariableSemantics, MemberOffset, SemanticMap, TextureSemantics, UniformMeta, VariableSemantics,
@ -120,9 +120,23 @@ pub struct FilterCommon {
pub(crate) quad_vbo: GLuint, pub(crate) quad_vbo: GLuint,
} }
type ShaderPassMeta<'a> = (
&'a ShaderPassConfig,
ShaderSource,
CompilerBackend<
impl CompileShader<GLSL, Options = GlVersion, Context = GlslangGlslContext>
+ ReflectShader
+ Sized,
>,
);
impl FilterChain { impl FilterChain {
pub fn load(path: impl AsRef<Path>) -> Result<FilterChain, Box<dyn Error>> { fn load_preset(
let preset = ShaderPreset::try_parse(path)?; preset: &ShaderPreset,
) -> (
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();
@ -186,14 +200,117 @@ impl FilterChain {
non_uniform_semantics: texture_semantics, non_uniform_semantics: texture_semantics,
}; };
(passes, semantics)
}
fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>, Box<dyn Error>> {
let mut luts = FxHashMap::default();
for (index, texture) in textures.iter().enumerate() {
let image = Image::load(&texture.path)?;
let levels = if texture.mipmap {
util::calc_miplevel(image.width, image.height)
} else {
1u32
};
let mut handle = 0;
unsafe {
gl::GenTextures(1, &mut handle);
gl::BindTexture(gl::TEXTURE_2D, handle);
gl::TexStorage2D(
gl::TEXTURE_2D,
levels as GLsizei,
gl::RGBA8,
image.width as GLsizei,
image.height as GLsizei,
);
gl::PixelStorei(gl::UNPACK_ROW_LENGTH, 0);
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 4);
gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, 0);
gl::TexSubImage2D(
gl::TEXTURE_2D,
0,
0,
0,
image.width as GLsizei,
image.height as GLsizei,
gl::RGBA,
gl::UNSIGNED_BYTE,
image.bytes.as_ptr().cast(),
);
let mipmap = levels > 1;
let linear = texture.filter_mode == FilterMode::Linear;
// set mipmaps and wrapping
if mipmap {
gl::GenerateMipmap(gl::TEXTURE_2D);
}
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_WRAP_S,
GLenum::from(texture.wrap_mode) as GLint,
);
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_WRAP_T,
GLenum::from(texture.wrap_mode) as GLint,
);
if !linear {
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
} else {
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as GLint);
if mipmap {
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_MIN_FILTER,
gl::LINEAR_MIPMAP_LINEAR as GLint,
);
} else {
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_MIN_FILTER,
gl::LINEAR as GLint,
);
}
}
gl::BindTexture(gl::TEXTURE_2D, 0);
}
luts.insert(
index,
Texture {
image: GlImage {
handle,
format: gl::RGBA8,
size: Size {
width: image.width,
height: image.height,
},
padded_size: Size::default(),
},
filter: texture.filter_mode,
mip_filter: texture.filter_mode,
wrap_mode: texture.wrap_mode,
},
);
}
Ok(luts)
}
pub fn init_passes(passes: Vec<ShaderPassMeta>, semantics: &ReflectSemantics) -> Result<Vec<FilterPass>, Box<dyn Error>> {
let mut filters = Vec::new(); let mut filters = Vec::new();
let mut output_framebuffers = Vec::new();
// initialize passes // initialize passes
for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() { for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() {
let semantics = semantics.clone(); let reflection = reflect.reflect(index, semantics)?;
let reflection = reflect.reflect(index, &semantics)?;
let glsl = reflect.compile(GlVersion::V4_60)?; let glsl = reflect.compile(GlVersion::V4_60)?;
let vertex_resources = glsl.context.compiler.vertex.get_shader_resources()?; let vertex_resources = glsl.context.compiler.vertex.get_shader_resources()?;
@ -327,9 +444,6 @@ impl FilterChain {
); );
} }
// need output framebuffers.
output_framebuffers.push(Framebuffer::new(1));
// eprintln!("{:#?}", semantics); // eprintln!("{:#?}", semantics);
// eprintln!("{:#?}", reflection.meta); // eprintln!("{:#?}", reflection.meta);
// eprintln!("{:#?}", locations); // eprintln!("{:#?}", locations);
@ -353,106 +467,26 @@ impl FilterChain {
}); });
} }
Ok(filters)
}
pub fn load(path: impl AsRef<Path>) -> Result<FilterChain, Box<dyn Error>> {
// 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)?;
// initialize output framebuffers
let mut output_framebuffers = Vec::new();
output_framebuffers.resize_with(filters.len(), || Framebuffer::new(1));
// load luts // load luts
let mut luts = FxHashMap::default(); let luts = FilterChain::load_luts(&preset.textures)?;
for (index, texture) in preset.textures.iter().enumerate() {
let image = Image::load(&texture.path)?;
let levels = if texture.mipmap {
util::calc_miplevel(image.width, image.height)
} else {
1u32
};
let mut handle = 0;
unsafe {
gl::GenTextures(1, &mut handle);
gl::BindTexture(gl::TEXTURE_2D, handle);
gl::TexStorage2D(
gl::TEXTURE_2D,
levels as GLsizei,
gl::RGBA8,
image.width as GLsizei,
image.height as GLsizei,
);
gl::PixelStorei(gl::UNPACK_ROW_LENGTH, 0);
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 4);
gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, 0);
gl::TexSubImage2D(
gl::TEXTURE_2D,
0,
0,
0,
image.width as GLsizei,
image.height as GLsizei,
gl::RGBA,
gl::UNSIGNED_BYTE,
image.bytes.as_ptr().cast(),
);
let mipmap = levels > 1;
let linear = texture.filter_mode == FilterMode::Linear;
// set mipmaps and wrapping
if mipmap {
gl::GenerateMipmap(gl::TEXTURE_2D);
}
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_WRAP_S,
GLenum::from(texture.wrap_mode) as GLint,
);
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_WRAP_T,
GLenum::from(texture.wrap_mode) as GLint,
);
if !linear {
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
} else {
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as GLint);
if mipmap {
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_MIN_FILTER,
gl::LINEAR_MIPMAP_LINEAR as GLint,
);
} else {
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_MIN_FILTER,
gl::LINEAR as GLint,
);
}
}
gl::BindTexture(gl::TEXTURE_2D, 0);
}
luts.insert(
index,
Texture {
image: GlImage {
handle,
format: gl::RGBA8,
size: Size {
width: image.width,
height: image.height,
},
padded_size: Size::default(),
},
filter: texture.filter_mode,
mip_filter: texture.filter_mode,
wrap_mode: texture.wrap_mode,
},
);
}
// create VBO objects
let mut quad_vbo = 0; let mut quad_vbo = 0;
unsafe { unsafe {
gl::GenBuffers(1, &mut quad_vbo); gl::GenBuffers(1, &mut quad_vbo);

View file

@ -535,7 +535,6 @@ void main()
gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4); gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
} }
framecount += 1; framecount += 1;
window.swap_buffers(); window.swap_buffers();
} }

View file

@ -1,4 +1,5 @@
#![feature(strict_provenance)] #![feature(strict_provenance)]
#![feature(type_alias_impl_trait)]
mod binding; mod binding;
mod filter_chain; mod filter_chain;

View file

@ -1,6 +1,7 @@
use crate::framebuffer::Framebuffer; use crate::framebuffer::Framebuffer;
use crate::util::Viewport; use crate::util::Viewport;
#[rustfmt::skip]
static DEFAULT_MVP: &[f32] = &[ static DEFAULT_MVP: &[f32] = &[
2f32, 0.0, 0.0, 0.0, 2f32, 0.0, 0.0, 0.0,
0.0, 2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0,

View file

@ -1,4 +1,3 @@
use gl::types::GLenum;
use crate::{FilterMode, ShaderFormat, WrapMode}; use crate::{FilterMode, ShaderFormat, WrapMode};
impl From<ShaderFormat> for gl::types::GLenum { impl From<ShaderFormat> for gl::types::GLenum {

View file

@ -1,5 +1,3 @@
use std::ffi::OsStr;
use std::io::ErrorKind;
use std::path::Path; use std::path::Path;
pub struct Image { pub struct Image {