gl: clean up filter_chain a little bit
This commit is contained in:
parent
eb582e396e
commit
23b13ef047
|
@ -4,15 +4,14 @@ use nom::branch::alt;
|
|||
use nom::bytes::complete::{is_not, take_until};
|
||||
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::sequence::{delimited, preceded};
|
||||
use nom::sequence::delimited;
|
||||
use nom::{
|
||||
bytes::complete::tag, character::complete::multispace0, IResult, InputIter, InputLength,
|
||||
InputTake,
|
||||
};
|
||||
use nom::multi::many0;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Token<'a> {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::error::ParsePresetError;
|
||||
use std::convert::Infallible;
|
||||
use std::ops::Mul;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
|
|
@ -7,9 +7,9 @@ use crate::util::{GlImage, RingBuffer, Size, Texture, Viewport};
|
|||
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
|
||||
use librashader::image::Image;
|
||||
use librashader::{FilterMode, ShaderSource};
|
||||
use librashader_presets::{ShaderPassConfig, ShaderPreset};
|
||||
use librashader_reflect::back::cross::GlVersion;
|
||||
use librashader_reflect::back::targets::{FromCompilation, GLSL};
|
||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||
use librashader_reflect::back::cross::{GlVersion, GlslangGlslContext};
|
||||
use librashader_reflect::back::targets::{CompilerBackend, FromCompilation, GLSL};
|
||||
use librashader_reflect::back::CompileShader;
|
||||
use librashader_reflect::reflect::semantics::{
|
||||
MemberOffset, SemanticMap, TextureSemantics, UniformMeta, VariableSemantics,
|
||||
|
@ -120,9 +120,23 @@ pub struct FilterCommon {
|
|||
pub(crate) quad_vbo: GLuint,
|
||||
}
|
||||
|
||||
type ShaderPassMeta<'a> = (
|
||||
&'a ShaderPassConfig,
|
||||
ShaderSource,
|
||||
CompilerBackend<
|
||||
impl CompileShader<GLSL, Options = GlVersion, Context = GlslangGlslContext>
|
||||
+ ReflectShader
|
||||
+ Sized,
|
||||
>,
|
||||
);
|
||||
|
||||
impl FilterChain {
|
||||
pub fn load(path: impl AsRef<Path>) -> Result<FilterChain, Box<dyn Error>> {
|
||||
let preset = ShaderPreset::try_parse(path)?;
|
||||
fn load_preset(
|
||||
preset: &ShaderPreset,
|
||||
) -> (
|
||||
Vec<ShaderPassMeta>,
|
||||
ReflectSemantics,
|
||||
) {
|
||||
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
||||
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
|
||||
Default::default();
|
||||
|
@ -186,14 +200,117 @@ impl FilterChain {
|
|||
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 output_framebuffers = Vec::new();
|
||||
|
||||
// initialize passes
|
||||
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 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!("{:#?}", reflection.meta);
|
||||
// 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
|
||||
let mut luts = FxHashMap::default();
|
||||
|
||||
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,
|
||||
},
|
||||
);
|
||||
}
|
||||
let luts = FilterChain::load_luts(&preset.textures)?;
|
||||
|
||||
// create VBO objects
|
||||
let mut quad_vbo = 0;
|
||||
unsafe {
|
||||
gl::GenBuffers(1, &mut quad_vbo);
|
||||
|
|
|
@ -535,7 +535,6 @@ void main()
|
|||
gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
|
||||
framecount += 1;
|
||||
window.swap_buffers();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#![feature(strict_provenance)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
mod binding;
|
||||
mod filter_chain;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::framebuffer::Framebuffer;
|
||||
use crate::util::Viewport;
|
||||
|
||||
#[rustfmt::skip]
|
||||
static DEFAULT_MVP: &[f32] = &[
|
||||
2f32, 0.0, 0.0, 0.0,
|
||||
0.0, 2.0, 0.0, 0.0,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use gl::types::GLenum;
|
||||
use crate::{FilterMode, ShaderFormat, WrapMode};
|
||||
|
||||
impl From<ShaderFormat> for gl::types::GLenum {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::ffi::OsStr;
|
||||
use std::io::ErrorKind;
|
||||
use std::path::Path;
|
||||
|
||||
pub struct Image {
|
||||
|
|
Loading…
Reference in a new issue