gl: clean up visibility in some APIs
This commit is contained in:
parent
df03fdc5eb
commit
4124ae3955
7 changed files with 123 additions and 117 deletions
|
@ -1,15 +1,15 @@
|
|||
use std::collections::VecDeque;
|
||||
use crate::binding::{UniformBinding, UniformLocation, VariableLocation};
|
||||
use crate::filter_pass::FilterPass;
|
||||
use crate::framebuffer::Framebuffer;
|
||||
use crate::framebuffer::{Framebuffer, GlImage, Size, Viewport};
|
||||
use crate::render_target::RenderTarget;
|
||||
use crate::util;
|
||||
use crate::util::{GlImage, InlineRingBuffer, Size, Texture, Viewport};
|
||||
use crate::util::{InlineRingBuffer, Texture};
|
||||
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
|
||||
use librashader::image::Image;
|
||||
use librashader::{FilterMode, ShaderSource, WrapMode};
|
||||
use librashader_presets::{ScaleType, ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||
use librashader_reflect::back::cross::{GlVersion, GlslangGlslContext};
|
||||
use librashader_reflect::back::cross::{GlslangGlslContext, GlVersion};
|
||||
use librashader_reflect::back::targets::{CompilerBackend, FromCompilation, GLSL};
|
||||
use librashader_reflect::back::CompileShader;
|
||||
use librashader_reflect::reflect::semantics::{
|
||||
|
@ -131,6 +131,68 @@ 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>> {
|
||||
let (passes, semantics) = FilterChain::load_preset(&preset);
|
||||
|
||||
// initialize passes
|
||||
let filters = FilterChain::init_passes(passes, &semantics)?;
|
||||
|
||||
let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default();
|
||||
let default_wrap = filters.first().map(|f| f.config.wrap_mode).unwrap_or_default();
|
||||
|
||||
// initialize output framebuffers
|
||||
let mut output_framebuffers = Vec::new();
|
||||
output_framebuffers.resize_with(filters.len(), || Framebuffer::new(1));
|
||||
let mut output_textures = Vec::new();
|
||||
output_textures.resize_with(filters.len(), Texture::default);
|
||||
|
||||
|
||||
// initialize feedback framebuffers
|
||||
let mut feedback_framebuffers = Vec::new();
|
||||
feedback_framebuffers.resize_with(filters.len(), || Framebuffer::new(1));
|
||||
let mut feedback_textures = Vec::new();
|
||||
feedback_textures.resize_with(filters.len(), Texture::default);
|
||||
|
||||
// load luts
|
||||
let luts = FilterChain::load_luts(&preset.textures)?;
|
||||
|
||||
let (history_framebuffers, history_textures) =
|
||||
FilterChain::init_history(&filters, default_filter, default_wrap);
|
||||
|
||||
// create VBO objects
|
||||
let draw_quad = DrawQuad::new();
|
||||
|
||||
let mut filter_vao = 0;
|
||||
unsafe {
|
||||
gl::GenVertexArrays(1, &mut filter_vao);
|
||||
}
|
||||
|
||||
Ok(FilterChain {
|
||||
passes: filters,
|
||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||
history_framebuffers,
|
||||
filter_vao,
|
||||
common: FilterCommon {
|
||||
semantics,
|
||||
preset,
|
||||
luts,
|
||||
output_textures: output_textures.into_boxed_slice(),
|
||||
feedback_textures: feedback_textures.into_boxed_slice(),
|
||||
history_textures,
|
||||
draw_quad,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/// 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>> {
|
||||
// load passes from preset
|
||||
let preset = ShaderPreset::try_parse(path)?;
|
||||
Self::load_from_preset(preset)
|
||||
}
|
||||
|
||||
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>> =
|
||||
|
@ -300,7 +362,7 @@ impl FilterChain {
|
|||
Ok(luts)
|
||||
}
|
||||
|
||||
pub fn init_passes(
|
||||
fn init_passes(
|
||||
passes: Vec<ShaderPassMeta>,
|
||||
semantics: &ReflectSemantics,
|
||||
) -> Result<Box<[FilterPass]>, Box<dyn Error>> {
|
||||
|
@ -467,7 +529,7 @@ impl FilterChain {
|
|||
Ok(filters.into_boxed_slice())
|
||||
}
|
||||
|
||||
pub fn init_history(filters: &[FilterPass], filter: FilterMode, wrap_mode: WrapMode) -> (VecDeque<Framebuffer>, Box<[Texture]>) {
|
||||
fn init_history(filters: &[FilterPass], filter: FilterMode, wrap_mode: WrapMode) -> (VecDeque<Framebuffer>, Box<[Texture]>) {
|
||||
let mut required_images = 0;
|
||||
|
||||
for pass in filters {
|
||||
|
@ -514,68 +576,7 @@ impl FilterChain {
|
|||
(framebuffers, history_textures.into_boxed_slice())
|
||||
}
|
||||
|
||||
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)?;
|
||||
|
||||
let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default();
|
||||
let default_wrap = filters.first().map(|f| f.config.wrap_mode).unwrap_or_default();
|
||||
|
||||
// initialize output framebuffers
|
||||
let mut output_framebuffers = Vec::new();
|
||||
output_framebuffers.resize_with(filters.len(), || Framebuffer::new(1));
|
||||
let mut output_textures = Vec::new();
|
||||
output_textures.resize_with(filters.len(), Texture::default);
|
||||
|
||||
|
||||
// initialize feedback framebuffers
|
||||
let mut feedback_framebuffers = Vec::new();
|
||||
feedback_framebuffers.resize_with(filters.len(), || Framebuffer::new(1));
|
||||
let mut feedback_textures = Vec::new();
|
||||
feedback_textures.resize_with(filters.len(), Texture::default);
|
||||
|
||||
// load luts
|
||||
let luts = FilterChain::load_luts(&preset.textures)?;
|
||||
|
||||
let (history_framebuffers, history_textures) =
|
||||
FilterChain::init_history(&filters, default_filter, default_wrap);
|
||||
|
||||
// create VBO objects
|
||||
let draw_quad = DrawQuad::new();
|
||||
|
||||
let mut filter_vao = 0;
|
||||
unsafe {
|
||||
gl::GenVertexArrays(1, &mut filter_vao);
|
||||
}
|
||||
|
||||
Ok(FilterChain {
|
||||
passes: filters,
|
||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||
history_framebuffers,
|
||||
filter_vao,
|
||||
common: FilterCommon {
|
||||
semantics,
|
||||
preset,
|
||||
luts,
|
||||
output_textures: output_textures.into_boxed_slice(),
|
||||
feedback_textures: feedback_textures.into_boxed_slice(),
|
||||
history_textures,
|
||||
draw_quad,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn get_output_texture(&self, index: usize) -> Texture {
|
||||
let config = &self.passes[index].config;
|
||||
self.output_framebuffers[index].as_texture(config.filter, config.wrap_mode)
|
||||
}
|
||||
|
||||
pub fn push_history(&mut self, input: &GlImage) {
|
||||
fn push_history(&mut self, input: &GlImage) {
|
||||
if let Some(mut back) = self.history_framebuffers.pop_back() {
|
||||
|
||||
if back.size != input.size
|
||||
|
@ -584,9 +585,7 @@ impl FilterChain {
|
|||
back.init(input.size, input.format);
|
||||
}
|
||||
|
||||
if back.is_initialized() {
|
||||
back.copy_from(&input);
|
||||
}
|
||||
|
||||
self.history_framebuffers.push_front(back)
|
||||
}
|
||||
|
|
|
@ -12,8 +12,9 @@ use rustc_hash::FxHashMap;
|
|||
|
||||
use crate::binding::{UniformBinding, UniformLocation, VariableLocation};
|
||||
use crate::filter_chain::FilterCommon;
|
||||
use crate::framebuffer::{Size, Viewport};
|
||||
use crate::render_target::RenderTarget;
|
||||
use crate::util::{InlineRingBuffer, RingBuffer, Size, Texture, Viewport};
|
||||
use crate::util::{InlineRingBuffer, RingBuffer, Texture};
|
||||
|
||||
pub struct FilterPass {
|
||||
pub reflection: ShaderReflection,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::util;
|
||||
use crate::util::{GlImage, Size, Texture, Viewport};
|
||||
use crate::util::Texture;
|
||||
use gl::types::{GLenum, GLint, GLsizei, GLuint};
|
||||
use librashader::{FilterMode, ShaderFormat, WrapMode};
|
||||
use librashader_presets::{Scale2D, ScaleType, Scaling};
|
||||
|
@ -7,12 +7,12 @@ use librashader_presets::{Scale2D, ScaleType, Scaling};
|
|||
#[derive(Debug)]
|
||||
pub struct Framebuffer {
|
||||
pub image: GLuint,
|
||||
pub handle: GLuint,
|
||||
pub size: Size,
|
||||
pub format: GLenum,
|
||||
pub max_levels: u32,
|
||||
pub levels: u32,
|
||||
pub handle: GLuint,
|
||||
pub init: bool,
|
||||
is_raw: bool,
|
||||
}
|
||||
|
||||
impl Framebuffer {
|
||||
|
@ -34,7 +34,7 @@ impl Framebuffer {
|
|||
max_levels,
|
||||
levels: 0,
|
||||
handle: framebuffer,
|
||||
init: false,
|
||||
is_raw: false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,11 +52,11 @@ impl Framebuffer {
|
|||
max_levels: miplevels,
|
||||
levels: miplevels,
|
||||
handle,
|
||||
init: true,
|
||||
is_raw: true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_texture(&self, filter: FilterMode, wrap_mode: WrapMode) -> Texture {
|
||||
pub(crate) fn as_texture(&self, filter: FilterMode, wrap_mode: WrapMode) -> Texture {
|
||||
Texture {
|
||||
image: GlImage {
|
||||
handle: self.image,
|
||||
|
@ -70,7 +70,7 @@ impl Framebuffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn scale(
|
||||
pub(crate) fn scale(
|
||||
&mut self,
|
||||
scaling: Scale2D,
|
||||
format: ShaderFormat,
|
||||
|
@ -78,6 +78,10 @@ impl Framebuffer {
|
|||
_original: &Texture,
|
||||
source: &Texture,
|
||||
) -> Size {
|
||||
if self.is_raw {
|
||||
return self.size;
|
||||
}
|
||||
|
||||
let mut width = 0f32;
|
||||
let mut height = 0f32;
|
||||
|
||||
|
@ -131,11 +135,7 @@ impl Framebuffer {
|
|||
size
|
||||
}
|
||||
|
||||
pub(crate) fn is_initialized(&self) -> bool {
|
||||
self.init
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
pub(crate) fn clear(&self) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.handle);
|
||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
||||
|
@ -145,7 +145,7 @@ impl Framebuffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn copy_from(&mut self, image: &GlImage) {
|
||||
pub(crate) fn copy_from(&mut self, image: &GlImage) {
|
||||
if image.size != self.size || image.format != self.format {
|
||||
self.init(image.size, image.format);
|
||||
}
|
||||
|
@ -190,9 +190,12 @@ impl Framebuffer {
|
|||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// todo: fix panic
|
||||
pub(crate) fn init(&mut self, mut size: Size, format: impl Into<GLenum>) {
|
||||
self.init = false;
|
||||
if self.is_raw {
|
||||
return;
|
||||
}
|
||||
self.format = format.into();
|
||||
self.size = size;
|
||||
|
||||
|
@ -283,13 +286,11 @@ impl Framebuffer {
|
|||
self.image,
|
||||
0,
|
||||
);
|
||||
self.init =
|
||||
gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
|
||||
// self.init =
|
||||
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
_ => panic!("failed to complete: {status:x}"),
|
||||
}
|
||||
} else {
|
||||
self.init = true;
|
||||
}
|
||||
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
|
@ -310,3 +311,25 @@ impl Drop for Framebuffer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Viewport<'a> {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub output: &'a Framebuffer,
|
||||
pub mvp: Option<&'a [f32]>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct Size {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone)]
|
||||
pub struct GlImage {
|
||||
pub handle: GLuint,
|
||||
pub format: GLenum,
|
||||
pub size: Size,
|
||||
pub padded_size: Size,
|
||||
}
|
||||
|
|
|
@ -7,8 +7,7 @@ use glfw::{Context, Glfw, Window, WindowEvent};
|
|||
use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint};
|
||||
|
||||
use crate::filter_chain::FilterChain;
|
||||
use crate::framebuffer::Framebuffer;
|
||||
use crate::util::{GlImage, Size, Viewport};
|
||||
use crate::framebuffer::{Framebuffer, GlImage, Size, Viewport};
|
||||
|
||||
const WIDTH: u32 = 900;
|
||||
const HEIGHT: u32 = 700;
|
||||
|
|
|
@ -10,6 +10,12 @@ mod render_target;
|
|||
mod util;
|
||||
mod quad_render;
|
||||
|
||||
pub use filter_chain::FilterChain;
|
||||
pub use framebuffer::Viewport;
|
||||
pub use framebuffer::GlImage;
|
||||
pub use framebuffer::Size;
|
||||
pub use framebuffer::Framebuffer;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -18,7 +24,7 @@ mod tests {
|
|||
#[test]
|
||||
fn triangle() {
|
||||
let (glfw, window, events, shader, vao) = hello_triangle::setup();
|
||||
let mut filter = FilterChain::load("../test/slang-shaders/crt/crt-royale-fake-bloom.slangp").unwrap();
|
||||
let mut filter = FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale-fake-bloom.slangp").unwrap();
|
||||
|
||||
// FilterChain::load("../test/slang-shaders/crt/crt-royale.slangp").unwrap();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::framebuffer::Framebuffer;
|
||||
use crate::util::{Texture, Viewport};
|
||||
use crate::framebuffer::{Framebuffer, Viewport};
|
||||
use crate::util::Texture;
|
||||
|
||||
#[rustfmt::skip]
|
||||
static DEFAULT_MVP: &[f32] = &[
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::framebuffer::Framebuffer;
|
||||
use crate::framebuffer::{Framebuffer, GlImage};
|
||||
use gl::types::{GLenum, GLuint};
|
||||
use librashader::{FilterMode, WrapMode};
|
||||
|
||||
|
@ -21,28 +21,6 @@ pub struct Texture {
|
|||
pub wrap_mode: WrapMode,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Viewport<'a> {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub output: &'a Framebuffer,
|
||||
pub mvp: Option<&'a [f32]>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct Size {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone)]
|
||||
pub struct GlImage {
|
||||
pub handle: GLuint,
|
||||
pub format: GLenum,
|
||||
pub size: Size,
|
||||
pub padded_size: Size,
|
||||
}
|
||||
|
||||
pub trait RingBuffer<T> {
|
||||
fn current(&self) -> &T;
|
||||
fn current_mut(&mut self) -> &mut T;
|
||||
|
|
Loading…
Add table
Reference in a new issue