gl: clean up visibility in some APIs

This commit is contained in:
chyyran 2022-11-21 02:56:03 -05:00
parent df03fdc5eb
commit 4124ae3955
7 changed files with 123 additions and 117 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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] = &[

View file

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