diff --git a/librashader-runtime-gl/src/binding.rs b/librashader-runtime-gl/src/binding.rs index ca5a0f7..450aef3 100644 --- a/librashader-runtime-gl/src/binding.rs +++ b/librashader-runtime-gl/src/binding.rs @@ -1,7 +1,8 @@ -use std::borrow::Borrow; -use std::hash::{Hash, Hasher}; use gl::types::GLint; -use librashader_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureSemantics, VariableSemantics}; +use librashader_reflect::reflect::semantics::{ + MemberOffset, SemanticMap, TextureSemantics, VariableSemantics, +}; +use std::hash::Hash; #[derive(Debug)] pub enum VariableLocation { @@ -12,7 +13,7 @@ pub enum VariableLocation { impl VariableLocation { pub fn location(&self) -> UniformLocation { match self { - VariableLocation::Ubo(l) | VariableLocation::Push(l) => *l + VariableLocation::Ubo(l) | VariableLocation::Push(l) => *l, } } } @@ -40,7 +41,7 @@ impl UniformLocation { #[derive(Debug, Copy, Clone)] pub enum MemberLocation { Offset(MemberOffset), - Uniform(UniformLocation) + Uniform(UniformLocation), } #[derive(Debug, Copy, Clone)] diff --git a/librashader-runtime-gl/src/filter_chain.rs b/librashader-runtime-gl/src/filter_chain.rs index 7193a58..b8b8305 100644 --- a/librashader-runtime-gl/src/filter_chain.rs +++ b/librashader-runtime-gl/src/filter_chain.rs @@ -1,33 +1,36 @@ -use rustc_hash::FxHashMap; -use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint}; -use librashader_presets::{ShaderPassConfig, ShaderPreset}; -use librashader_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureSemantics, UniformMeta, VariableSemantics}; -use librashader_reflect::reflect::{ReflectSemantics, ReflectShader, UniformSemantic}; -use std::path::Path; -use std::error::Error; -use librashader::{FilterMode, ShaderSource}; -use librashader_reflect::back::cross::GlVersion; -use librashader_reflect::back::targets::{FromCompilation, GLSL}; -use spirv_cross::spirv::Decoration; -use librashader::image::Image; -use librashader_reflect::back::CompileShader; use crate::binding::{UniformBinding, UniformLocation, VariableLocation}; use crate::filter_pass::FilterPass; use crate::framebuffer::Framebuffer; use crate::render_target::RenderTarget; use crate::util; 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_reflect::back::CompileShader; +use librashader_reflect::reflect::semantics::{ + MemberOffset, SemanticMap, TextureSemantics, UniformMeta, VariableSemantics, +}; +use librashader_reflect::reflect::{ReflectSemantics, ReflectShader, UniformSemantic}; +use rustc_hash::FxHashMap; +use spirv_cross::spirv::Decoration; +use std::error::Error; +use std::path::Path; -static QUAD_VBO_DATA: &'static [f32; 16] = &[ - 0.0f32, 0.0f32, 0.0f32, 0.0f32, - 1.0f32, 0.0f32, 1.0f32, 0.0f32, - 0.0f32, 1.0f32, 0.0f32, 1.0f32, +static QUAD_VBO_DATA: &[f32; 16] = &[ + 0.0f32, 0.0f32, 0.0f32, 0.0f32, 1.0f32, 0.0f32, 1.0f32, 0.0f32, 0.0f32, 1.0f32, 0.0f32, 1.0f32, 1.0f32, 1.0f32, 1.0f32, 1.0f32, ]; impl FilterChain { - fn load_pass_semantics(uniform_semantics: &mut FxHashMap, texture_semantics: &mut FxHashMap>, - config: &ShaderPassConfig) { + fn load_pass_semantics( + uniform_semantics: &mut FxHashMap, + texture_semantics: &mut FxHashMap>, + config: &ShaderPassConfig, + ) { let Some(alias) = &config.alias else { return; }; @@ -40,24 +43,36 @@ impl FilterChain { let index = config.id as usize; // PassOutput - texture_semantics.insert(alias.clone(), SemanticMap { - semantics: TextureSemantics::PassOutput, - index - }); - uniform_semantics.insert(format!("{alias}Size"), UniformSemantic::Texture(SemanticMap { - semantics: TextureSemantics::PassOutput, - index - })); + texture_semantics.insert( + alias.clone(), + SemanticMap { + semantics: TextureSemantics::PassOutput, + index, + }, + ); + uniform_semantics.insert( + format!("{alias}Size"), + UniformSemantic::Texture(SemanticMap { + semantics: TextureSemantics::PassOutput, + index, + }), + ); // PassFeedback - texture_semantics.insert(format!("{alias}Feedback"), SemanticMap { - semantics: TextureSemantics::PassFeedback, - index - }); - uniform_semantics.insert(format!("{alias}FeedbackSize"), UniformSemantic::Texture(SemanticMap { - semantics: TextureSemantics::PassFeedback, - index - })); + texture_semantics.insert( + format!("{alias}Feedback"), + SemanticMap { + semantics: TextureSemantics::PassFeedback, + index, + }, + ); + uniform_semantics.insert( + format!("{alias}FeedbackSize"), + UniformSemantic::Texture(SemanticMap { + semantics: TextureSemantics::PassFeedback, + index, + }), + ); } fn reflect_uniform_location(pipeline: GLuint, meta: &impl UniformMeta) -> VariableLocation { @@ -71,10 +86,7 @@ impl FilterChain { let vertex = gl::GetUniformLocation(pipeline, vert_name.as_ptr().cast()); let fragment = gl::GetUniformLocation(pipeline, frag_name.as_ptr().cast()); - VariableLocation::Ubo(UniformLocation { - vertex, - fragment - }) + VariableLocation::Ubo(UniformLocation { vertex, fragment }) } } MemberOffset::PushConstant(_) => { @@ -84,15 +96,11 @@ impl FilterChain { let vertex = gl::GetUniformLocation(pipeline, vert_name.as_ptr().cast()); let fragment = gl::GetUniformLocation(pipeline, frag_name.as_ptr().cast()); - VariableLocation::Push(UniformLocation { - vertex, - fragment - }) + VariableLocation::Push(UniformLocation { vertex, fragment }) } } } } - } pub struct FilterChain { @@ -116,50 +124,66 @@ impl FilterChain { pub fn load(path: impl AsRef) -> Result> { let preset = ShaderPreset::try_parse(path)?; let mut uniform_semantics: FxHashMap = Default::default(); - let mut texture_semantics: FxHashMap> = Default::default(); + let mut texture_semantics: FxHashMap> = + Default::default(); - let mut passes: Vec<(&ShaderPassConfig, ShaderSource, _)> = preset.shaders.iter() + let passes: Vec<(&ShaderPassConfig, ShaderSource, _)> = preset + .shaders + .iter() .map(|shader| { eprintln!("[gl] loading {}", &shader.name.display()); - let source: ShaderSource = librashader_preprocess::load_shader_source(&shader.name) - .unwrap(); + let source: ShaderSource = + librashader_preprocess::load_shader_source(&shader.name).unwrap(); - let spirv = librashader_reflect::front::shaderc::compile_spirv(&source) - .unwrap(); - let mut reflect = GLSL::from_compilation(spirv).unwrap(); + let spirv = librashader_reflect::front::shaderc::compile_spirv(&source).unwrap(); + let reflect = GLSL::from_compilation(spirv).unwrap(); for parameter in source.parameters.iter() { - uniform_semantics.insert(parameter.id.clone(), UniformSemantic::Variable(SemanticMap { - semantics: VariableSemantics::FloatParameter, - index: () - })); + uniform_semantics.insert( + parameter.id.clone(), + UniformSemantic::Variable(SemanticMap { + semantics: VariableSemantics::FloatParameter, + index: (), + }), + ); } (shader, source, reflect) - }).collect(); + }) + .collect(); // todo: this can probably be extracted out. for details in &passes { - FilterChain::load_pass_semantics(&mut uniform_semantics, &mut texture_semantics, details.0) + FilterChain::load_pass_semantics( + &mut uniform_semantics, + &mut texture_semantics, + details.0, + ) } // add lut params for (index, texture) in preset.textures.iter().enumerate() { - texture_semantics.insert(texture.name.clone(), SemanticMap { - semantics: TextureSemantics::User, - index - }); + texture_semantics.insert( + texture.name.clone(), + SemanticMap { + semantics: TextureSemantics::User, + index, + }, + ); - uniform_semantics.insert(format!("{}Size", texture.name), UniformSemantic::Texture(SemanticMap { - semantics: TextureSemantics::User, - index - })); + uniform_semantics.insert( + format!("{}Size", texture.name), + UniformSemantic::Texture(SemanticMap { + semantics: TextureSemantics::User, + index, + }), + ); } let semantics = ReflectSemantics { uniform_semantics, - non_uniform_semantics: texture_semantics + non_uniform_semantics: texture_semantics, }; let mut filters = Vec::new(); @@ -167,7 +191,7 @@ impl FilterChain { // initialize passes for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() { - let mut semantics = semantics.clone(); + let semantics = semantics.clone(); let reflection = reflect.reflect(index, &semantics)?; let glsl = reflect.compile(GlVersion::V4_60)?; @@ -184,7 +208,11 @@ impl FilterChain { gl::AttachShader(program, fragment); for res in &vertex_resources.stage_inputs { - let loc = glsl.context.compiler.vertex.get_decoration(res.id, Decoration::Location)?; + let loc = glsl + .context + .compiler + .vertex + .get_decoration(res.id, Decoration::Location)?; let loc_name = format!("LIBRA_ATTRIBUTE_{loc}\0"); eprintln!("{loc_name}"); gl::BindAttribLocation(program, loc, loc_name.as_str().as_ptr().cast()) @@ -203,7 +231,8 @@ impl FilterChain { for binding in &glsl.context.sampler_bindings { let loc_name = format!("LIBRA_TEXTURE_{}\0", *binding); - let location = gl::GetUniformLocation(program, loc_name.as_str().as_ptr().cast()); + let location = + gl::GetUniformLocation(program, loc_name.as_str().as_ptr().cast()); if location >= 0 { // eprintln!("setting sampler {location} to sample from {binding}"); gl::Uniform1i(location, *binding as GLint); @@ -211,10 +240,19 @@ impl FilterChain { } gl::UseProgram(0); - (program, UniformLocation { - vertex: gl::GetUniformBlockIndex(program, b"LIBRA_UBO_VERTEX\0".as_ptr().cast()), - fragment: gl::GetUniformBlockIndex(program, b"LIBRA_UBO_FRAGMENT\0".as_ptr().cast()), - }) + ( + program, + UniformLocation { + vertex: gl::GetUniformBlockIndex( + program, + b"LIBRA_UBO_VERTEX\0".as_ptr().cast(), + ), + fragment: gl::GetUniformBlockIndex( + program, + b"LIBRA_UBO_FRAGMENT\0".as_ptr().cast(), + ), + }, + ) }; let ubo_ring = if let Some(ubo) = &reflection.ubo { @@ -224,7 +262,12 @@ impl FilterChain { gl::GenBuffers(16, ring.items_mut().as_mut_ptr()); for buffer in ring.items() { gl::BindBuffer(gl::UNIFORM_BUFFER, *buffer); - gl::BufferData(gl::UNIFORM_BUFFER, size as GLsizeiptr, std::ptr::null(), gl::STREAM_DRAW); + gl::BufferData( + gl::UNIFORM_BUFFER, + size as GLsizeiptr, + std::ptr::null(), + gl::STREAM_DRAW, + ); } gl::BindBuffer(gl::UNIFORM_BUFFER, 0); } @@ -233,24 +276,55 @@ impl FilterChain { None }; - let uniform_buffer = vec![0; reflection.ubo.as_ref().map(|ubo| ubo.size as usize).unwrap_or(0)].into_boxed_slice(); - let push_buffer = vec![0; reflection.push_constant.as_ref().map(|push| push.size as usize).unwrap_or(0)].into_boxed_slice(); + let uniform_buffer = vec![ + 0; + reflection + .ubo + .as_ref() + .map(|ubo| ubo.size as usize) + .unwrap_or(0) + ] + .into_boxed_slice(); + let push_buffer = vec![ + 0; + reflection + .push_constant + .as_ref() + .map(|push| push.size as usize) + .unwrap_or(0) + ] + .into_boxed_slice(); // todo: reflect indexed parameters let mut locations = FxHashMap::default(); for param in reflection.meta.parameter_meta.values() { - locations.insert(UniformBinding::Parameter(param.id.clone()), - (FilterChain::reflect_uniform_location(program, param), param.offset)); + locations.insert( + UniformBinding::Parameter(param.id.clone()), + ( + FilterChain::reflect_uniform_location(program, param), + param.offset, + ), + ); } for (semantics, param) in &reflection.meta.variable_meta { - locations.insert(UniformBinding::SemanticVariable(semantics.clone()), - (FilterChain::reflect_uniform_location(program, param), param.offset)); + locations.insert( + UniformBinding::SemanticVariable(*semantics), + ( + FilterChain::reflect_uniform_location(program, param), + param.offset, + ), + ); } for (semantics, param) in &reflection.meta.texture_size_meta { - locations.insert(UniformBinding::TextureSize(semantics.clone()), - (FilterChain::reflect_uniform_location(program, param), param.offset)); + locations.insert( + UniformBinding::TextureSize(*semantics), + ( + FilterChain::reflect_uniform_location(program, param), + param.offset, + ), + ); } // need output framebuffers. @@ -275,7 +349,7 @@ impl FilterChain { push_buffer, variable_bindings: locations, source, - config: config.clone() + config: config.clone(), }); } @@ -294,15 +368,28 @@ impl FilterChain { 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::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()); + 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; @@ -313,8 +400,16 @@ impl FilterChain { 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); + 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); @@ -322,39 +417,52 @@ impl FilterChain { } 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); + 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::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 + luts.insert( + index, + Texture { + image: GlImage { + handle, + format: gl::RGBA8, + size: Size { + width: image.width, + height: image.height, + }, + padded_size: Size::default(), }, - padded_size: Size::default() + filter: texture.filter_mode, + mip_filter: texture.filter_mode, + wrap_mode: texture.wrap_mode, }, - filter: texture.filter_mode, - mip_filter: texture.filter_mode, - wrap_mode: texture.wrap_mode - }); + ); } let mut quad_vbo = 0; unsafe { gl::GenBuffers(1, &mut quad_vbo); gl::BindBuffer(gl::ARRAY_BUFFER, quad_vbo); - gl::BufferData(gl::ARRAY_BUFFER, std::mem::size_of_val(QUAD_VBO_DATA) as GLsizeiptr, - QUAD_VBO_DATA.as_ptr().cast(), gl::STATIC_DRAW); + gl::BufferData( + gl::ARRAY_BUFFER, + std::mem::size_of_val(QUAD_VBO_DATA) as GLsizeiptr, + QUAD_VBO_DATA.as_ptr().cast(), + gl::STATIC_DRAW, + ); gl::BindBuffer(gl::ARRAY_BUFFER, 0); } @@ -375,11 +483,11 @@ impl FilterChain { luts, outputs: output_framebuffers, quad_vbo, - } + }, }) } - pub fn frame(&mut self, count: u32, vp: &Viewport, input: GlImage, clear: bool) { + pub fn frame(&mut self, count: u32, vp: &Viewport, input: GlImage, _clear: bool) { if self.passes.is_empty() { return; } @@ -391,17 +499,29 @@ impl FilterChain { // todo: copy framebuffer // shader_gl3: 2067 - let filter = self.common.preset.shaders.first().map(|f| f.filter).unwrap_or_default(); - let wrap_mode = self.common.preset.shaders.first().map(|f| f.wrap_mode).unwrap_or_default(); + let filter = self + .common + .preset + .shaders + .first() + .map(|f| f.filter) + .unwrap_or_default(); + let wrap_mode = self + .common + .preset + .shaders + .first() + .map(|f| f.wrap_mode) + .unwrap_or_default(); let original = Texture { image: input, filter, mip_filter: filter, - wrap_mode + wrap_mode, }; - let mut source = original.clone(); + let mut source = original; let passes_len = self.passes.len(); let (pass, last) = self.passes.split_at_mut(passes_len - 1); @@ -409,10 +529,24 @@ impl FilterChain { for (index, pass) in pass.iter_mut().enumerate() { { let target = &mut self.common.outputs[index]; - let framebuffer_size = target.scale(pass.config.scaling.clone(), pass.get_format(), vp, &original, &source); + let _framebuffer_size = target.scale( + pass.config.scaling.clone(), + pass.get_format(), + vp, + &original, + &source, + ); } let target = &self.common.outputs[index]; - pass.draw(&self.common, count, 1, vp, &original, &source, RenderTarget::new(target, None)); + pass.draw( + &self.common, + count, + 1, + vp, + &original, + &source, + RenderTarget::new(target, None), + ); let target = target.as_texture(pass.config.filter, pass.config.wrap_mode); // todo: update-pass-outputs @@ -424,7 +558,15 @@ impl FilterChain { for pass in last { source.filter = pass.config.filter; source.mip_filter = pass.config.filter; - pass.draw(&self.common, count, 1, vp, &original, &source, RenderTarget::new(&vp.output, vp.mvp)); + pass.draw( + &self.common, + count, + 1, + vp, + &original, + &source, + RenderTarget::new(vp.output, vp.mvp), + ); } unsafe { diff --git a/librashader-runtime-gl/src/filter_pass.rs b/librashader-runtime-gl/src/filter_pass.rs index e3f4089..3b86467 100644 --- a/librashader-runtime-gl/src/filter_pass.rs +++ b/librashader-runtime-gl/src/filter_pass.rs @@ -1,20 +1,19 @@ -use std::borrow::Borrow; -use std::iter::Filter; use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint}; use librashader_reflect::back::cross::GlslangGlslContext; use librashader_reflect::back::ShaderCompilerOutput; use librashader_reflect::reflect::ShaderReflection; -use librashader_reflect::reflect::TextureSemanticMap; -use librashader_reflect::reflect::VariableSemanticMap; -use rustc_hash::FxHashMap; + use librashader::{ShaderFormat, ShaderSource}; -use librashader_presets::{Scale2D, ScaleType, Scaling, ShaderPassConfig, ShaderPreset}; -use librashader_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureImage, TextureSemantics, VariableMeta, VariableSemantics}; -use crate::framebuffer::Framebuffer; +use librashader_presets::ShaderPassConfig; +use librashader_reflect::reflect::semantics::{ + MemberOffset, TextureImage, TextureSemantics, VariableSemantics, +}; +use rustc_hash::FxHashMap; + use crate::binding::{UniformBinding, UniformLocation, VariableLocation}; -use crate::filter_chain::{FilterChain, FilterCommon}; +use crate::filter_chain::FilterCommon; use crate::render_target::RenderTarget; -use crate::util::{GlImage, RingBuffer, Size, Texture, Viewport}; +use crate::util::{RingBuffer, Size, Texture, Viewport}; pub struct FilterPass { pub reflection: ShaderReflection, @@ -26,7 +25,7 @@ pub struct FilterPass { pub push_buffer: Box<[u8]>, pub variable_bindings: FxHashMap, pub source: ShaderSource, - pub config: ShaderPassConfig + pub config: ShaderPassConfig, } impl FilterPass { @@ -36,7 +35,12 @@ impl FilterPass { } fn build_vec4(location: UniformLocation, buffer: &mut [u8], size: Size) { - let vec4 = [size.width as f32, size.height as f32, 1.0 / size.width as f32, 1.0/ size.height as f32]; + let vec4 = [ + size.width as f32, + size.height as f32, + 1.0 / size.width as f32, + 1.0 / size.height as f32, + ]; if location.fragment >= 0 || location.vertex >= 0 { unsafe { if location.vertex >= 0 { @@ -53,8 +57,14 @@ impl FilterPass { } #[inline(always)] - fn build_uniform(location: UniformLocation, buffer: &mut [u8], value: T, glfn: unsafe fn(GLint, T) -> ()) - where T: Copy, T: bytemuck::Pod + fn build_uniform( + location: UniformLocation, + buffer: &mut [u8], + value: T, + glfn: unsafe fn(GLint, T) -> (), + ) where + T: Copy, + T: bytemuck::Pod, { if location.fragment >= 0 || location.vertex >= 0 { unsafe { @@ -66,7 +76,7 @@ impl FilterPass { } } } else { - let mut buffer = bytemuck::cast_slice_mut(buffer); + let buffer = bytemuck::cast_slice_mut(buffer); buffer[0] = value; } } @@ -89,10 +99,26 @@ impl FilterPass { gl::ActiveTexture(gl::TEXTURE0 + binding.binding); gl::BindTexture(gl::TEXTURE_2D, texture.image.handle); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, GLenum::from(texture.filter) as GLint); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, texture.filter.gl_mip(texture.mip_filter) as GLint); - 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); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_MAG_FILTER, + GLenum::from(texture.filter) as GLint, + ); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_MIN_FILTER, + texture.filter.gl_mip(texture.mip_filter) as GLint, + ); + 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, + ); } } @@ -107,9 +133,16 @@ impl FilterPass { } // todo: fix rendertargets (i.e. non-final pass is internal, final pass is user provided fbo) - pub fn draw(&mut self, parent: &FilterCommon, frame_count: u32, - frame_direction: i32, viewport: &Viewport, original: &Texture, source: &Texture, output: RenderTarget) { - + pub fn draw( + &mut self, + parent: &FilterCommon, + frame_count: u32, + frame_direction: i32, + viewport: &Viewport, + original: &Texture, + source: &Texture, + output: RenderTarget, + ) { let framebuffer = output.framebuffer; unsafe { @@ -117,18 +150,33 @@ impl FilterPass { gl::UseProgram(self.program); } - self.build_semantics(parent, output.mvp, frame_count, frame_direction, framebuffer.size, viewport, original, source); + self.build_semantics( + parent, + output.mvp, + frame_count, + frame_direction, + framebuffer.size, + viewport, + original, + source, + ); // shader_gl3:1514 - if self.ubo_location.vertex != gl::INVALID_INDEX && self.ubo_location.fragment != gl::INVALID_INDEX { + if self.ubo_location.vertex != gl::INVALID_INDEX + && self.ubo_location.fragment != gl::INVALID_INDEX + { if let (Some(ubo), Some(ring)) = (&self.reflection.ubo, &mut self.ubo_ring) { let size = ubo.size; let buffer = ring.current(); unsafe { gl::BindBuffer(gl::UNIFORM_BUFFER, *buffer); - gl::BufferSubData(gl::UNIFORM_BUFFER, 0, size as GLsizeiptr, - self.uniform_buffer.as_ptr().cast()); + gl::BufferSubData( + gl::UNIFORM_BUFFER, + 0, + size as GLsizeiptr, + self.uniform_buffer.as_ptr().cast(), + ); gl::BindBuffer(gl::UNIFORM_BUFFER, 0); if self.ubo_location.vertex != gl::INVALID_INDEX { @@ -150,7 +198,12 @@ impl FilterPass { gl::ClearColor(0.0f32, 0.0f32, 0.0f32, 0.0f32); gl::Clear(gl::COLOR_BUFFER_BIT); // - gl::Viewport(0, 0, framebuffer.size.width as GLsizei, framebuffer.size.height as GLsizei); + gl::Viewport( + 0, + 0, + framebuffer.size.width as GLsizei, + framebuffer.size.height as GLsizei, + ); if framebuffer.format == gl::SRGB8_ALPHA8 { gl::Enable(gl::FRAMEBUFFER_SRGB); @@ -170,13 +223,24 @@ impl FilterPass { /// the provided pointers are of OpenGL provenance with respect to the buffer bound to quad_vbo, /// and not a known provenance to the Rust abstract machine, therefore we give it invalid pointers. /// that are inexpressible in Rust - gl::VertexAttribPointer(0, 2, gl::FLOAT, gl::FALSE, (4 * std::mem::size_of::()) as GLsizei, - std::ptr::invalid(0)); - gl::VertexAttribPointer(1, 2, gl::FLOAT, gl::FALSE, (4 * std::mem::size_of::()) as GLsizei, - std::ptr::invalid(2 * std::mem::size_of::())); + gl::VertexAttribPointer( + 0, + 2, + gl::FLOAT, + gl::FALSE, + (4 * std::mem::size_of::()) as GLsizei, + std::ptr::invalid(0), + ); + gl::VertexAttribPointer( + 1, + 2, + gl::FLOAT, + gl::FALSE, + (4 * std::mem::size_of::()) as GLsizei, + std::ptr::invalid(2 * std::mem::size_of::()), + ); gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4); - gl::BindBuffer(gl::ARRAY_BUFFER, 0); gl::DisableVertexAttribArray(0); gl::DisableVertexAttribArray(1); @@ -185,78 +249,133 @@ impl FilterPass { gl::BindFramebuffer(gl::FRAMEBUFFER, 0); } - // todo: draw image onto fbo // shader_gl3 1579 } // framecount should be pre-modded - fn build_semantics(&mut self, parent: &FilterCommon, mvp: &[f32], frame_count: u32, frame_direction: i32, fb_size: Size, viewport: &Viewport, original: &Texture, source: &Texture) { - if let Some((_location, offset)) = self.variable_bindings.get(&VariableSemantics::MVP.into()) { - let mvp_size = mvp.len() * std::mem::size_of::(); - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset) - }; - FilterPass::build_mvp(&mut buffer[offset..][..mvp_size], mvp) - } - - if let Some((location, offset)) = self.variable_bindings.get(&VariableSemantics::Output.into()) { + fn build_semantics( + &mut self, + parent: &FilterCommon, + mvp: &[f32], + frame_count: u32, + frame_direction: i32, + fb_size: Size, + viewport: &Viewport, + original: &Texture, + source: &Texture, + ) { + if let Some((_location, offset)) = + self.variable_bindings.get(&VariableSemantics::MVP.into()) + { + let mvp_size = mvp.len() * std::mem::size_of::(); let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset) + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), + }; + FilterPass::build_mvp(&mut buffer[offset..][..mvp_size], mvp) + } + + if let Some((location, offset)) = self + .variable_bindings + .get(&VariableSemantics::Output.into()) + { + let (buffer, offset) = match offset { + MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), }; FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], fb_size) } - if let Some((location, offset)) = self.variable_bindings.get(&VariableSemantics::FinalViewport.into()) { + if let Some((location, offset)) = self + .variable_bindings + .get(&VariableSemantics::FinalViewport.into()) + { let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset) + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), }; - FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], viewport.output.size) + FilterPass::build_vec4( + location.location(), + &mut buffer[offset..][..4], + viewport.output.size, + ) } - if let Some((location, offset)) = self.variable_bindings.get(&VariableSemantics::FrameCount.into()) { + if let Some((location, offset)) = self + .variable_bindings + .get(&VariableSemantics::FrameCount.into()) + { let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset) + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), }; FilterPass::build_uint(location.location(), &mut buffer[offset..][..4], frame_count) } - if let Some((location, offset)) = self.variable_bindings.get(&VariableSemantics::FrameDirection.into()) { + if let Some((location, offset)) = self + .variable_bindings + .get(&VariableSemantics::FrameDirection.into()) + { let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset) + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), }; - FilterPass::build_sint(location.location(), &mut buffer[offset..][..4], frame_direction) + FilterPass::build_sint( + location.location(), + &mut buffer[offset..][..4], + frame_direction, + ) } - if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::Original.semantics(0)) { + if let Some(binding) = self + .reflection + .meta + .texture_meta + .get(&TextureSemantics::Original.semantics(0)) + { eprintln!("setting original binding to {}", binding.binding); FilterPass::bind_texture(binding, original); } - if let Some((location, offset)) = self.variable_bindings.get(&TextureSemantics::Original.semantics(0).into()) { + if let Some((location, offset)) = self + .variable_bindings + .get(&TextureSemantics::Original.semantics(0).into()) + { let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset) + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), }; - FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], original.image.size); + FilterPass::build_vec4( + location.location(), + &mut buffer[offset..][..4], + original.image.size, + ); } - if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::Source.semantics(0)) { + if let Some(binding) = self + .reflection + .meta + .texture_meta + .get(&TextureSemantics::Source.semantics(0)) + { // eprintln!("setting source binding to {}", binding.binding); FilterPass::bind_texture(binding, source); } - if let Some((location, offset)) = self.variable_bindings.get(&TextureSemantics::Source.semantics(0).into()) { + if let Some((location, offset)) = self + .variable_bindings + .get(&TextureSemantics::Source.semantics(0).into()) + { let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset) + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), }; - FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], source.image.size); + FilterPass::build_vec4( + location.location(), + &mut buffer[offset..][..4], + source.image.size, + ); } // // todo: history @@ -273,60 +392,72 @@ impl FilterPass { // // FilterPass::build_vec4(location, &mut buffer[offset..][..4], original.image.size); // // } // - for (id, (location, offset)) in self.variable_bindings.iter() - .filter_map(|(binding, value)| match binding { - UniformBinding::Parameter(id) => { - Some((id, value)) - } - _ => None - }) + for (id, (location, offset)) in + self.variable_bindings + .iter() + .filter_map(|(binding, value)| match binding { + UniformBinding::Parameter(id) => Some((id, value)), + _ => None, + }) { let id = id.as_str(); let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset) + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), }; // presets override params - let default = self.source.parameters.iter().find(|&p| p.id == id) + let default = self + .source + .parameters + .iter() + .find(|&p| p.id == id) .map(|f| f.initial) .unwrap_or(0f32); - let value = parent.preset.parameters.iter().find(|&p| p.name == id) + let value = parent + .preset + .parameters + .iter() + .find(|&p| p.name == id) .map(|p| p.value) .unwrap_or(default); FilterPass::build_float(location.location(), &mut buffer[offset..][..4], value) } - for (id, (location, offset)) in self.variable_bindings.iter() - .filter_map(|(binding, value)| match binding { - UniformBinding::TextureSize(semantics) => { - if semantics.semantics == TextureSemantics::User { - Some((semantics, value)) - } else { - None + for (id, (location, offset)) in + self.variable_bindings + .iter() + .filter_map(|(binding, value)| match binding { + UniformBinding::TextureSize(semantics) => { + if semantics.semantics == TextureSemantics::User { + Some((semantics, value)) + } else { + None + } } - } - _ => None - }) + _ => None, + }) { let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset) + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset), }; if let Some(lut) = parent.luts.get(&id.index) { - if let Some(binding) = self.reflection.meta.texture_meta.get(&id) { + if let Some(binding) = self.reflection.meta.texture_meta.get(id) { FilterPass::bind_texture(binding, lut); } - FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], - lut.image.size); + FilterPass::build_vec4( + location.location(), + &mut buffer[offset..][..4], + lut.image.size, + ); } } - // // todo history } -} \ No newline at end of file +} diff --git a/librashader-runtime-gl/src/framebuffer.rs b/librashader-runtime-gl/src/framebuffer.rs index 78a18ae..3c32ecf 100644 --- a/librashader-runtime-gl/src/framebuffer.rs +++ b/librashader-runtime-gl/src/framebuffer.rs @@ -1,8 +1,8 @@ +use crate::util; +use crate::util::{GlImage, Size, Texture, Viewport}; use gl::types::{GLenum, GLsizei, GLuint}; use librashader::{FilterMode, ShaderFormat, WrapMode}; use librashader_presets::{Scale2D, ScaleType, Scaling}; -use crate::util; -use crate::util::{GlImage, Size, Texture, Viewport}; #[derive(Debug)] pub struct Framebuffer { @@ -12,7 +12,7 @@ pub struct Framebuffer { pub max_levels: u32, pub levels: u32, pub handle: GLuint, - pub init: bool + pub init: bool, } impl Framebuffer { @@ -26,24 +26,33 @@ impl Framebuffer { Framebuffer { image: 0, - size: Size { width: 1, height: 1 }, + size: Size { + width: 1, + height: 1, + }, format: 0, max_levels, levels: 0, handle: framebuffer, - init: false + init: false, } } - pub fn new_from_raw(texture: GLuint, handle: GLuint, format: GLenum, size: Size, miplevels: u32) -> Framebuffer { + pub fn new_from_raw( + texture: GLuint, + handle: GLuint, + format: GLenum, + size: Size, + miplevels: u32, + ) -> Framebuffer { Framebuffer { image: texture, size, format, max_levels: miplevels, levels: miplevels, - handle: handle, - init: true + handle, + init: true, } } @@ -53,78 +62,76 @@ impl Framebuffer { handle: self.image, format: self.format, size: self.size, - padded_size: Default::default() + padded_size: Default::default(), }, filter, mip_filter: filter, - wrap_mode + wrap_mode, } } - pub fn scale(&mut self, scaling: Scale2D, format: ShaderFormat, viewport: &Viewport, original: &Texture, source: &Texture) -> Size { + pub fn scale( + &mut self, + scaling: Scale2D, + format: ShaderFormat, + viewport: &Viewport, + _original: &Texture, + source: &Texture, + ) -> Size { let mut width = 0f32; let mut height = 0f32; match scaling.x { Scaling { scale_type: ScaleType::Input, - factor - } => { - width = source.image.size.width * factor - }, + factor, + } => width = source.image.size.width * factor, Scaling { scale_type: ScaleType::Absolute, - factor - } => { - width = factor.into() - } + factor, + } => width = factor.into(), Scaling { scale_type: ScaleType::Viewport, - factor - } => { - width = viewport.output.size.width * factor - } + factor, + } => width = viewport.output.size.width * factor, }; match scaling.y { Scaling { scale_type: ScaleType::Input, - factor - } => { - height = source.image.size.height * factor - }, + factor, + } => height = source.image.size.height * factor, Scaling { scale_type: ScaleType::Absolute, - factor - } => { - height = factor.into() - } + factor, + } => height = factor.into(), Scaling { scale_type: ScaleType::Viewport, - factor - } => { - height = viewport.output.size.height * factor - } + factor, + } => height = viewport.output.size.height * factor, }; let size = Size { width: width.round() as u32, - height: height.round() as u32 + height: height.round() as u32, }; if self.size != size { self.size = size; - self.init(size,if format == ShaderFormat::Unknown { - ShaderFormat::R8G8B8A8Unorm - } else { - format - }); + self.init( + size, + if format == ShaderFormat::Unknown { + ShaderFormat::R8G8B8A8Unorm + } else { + format + }, + ); } size } - fn init(&mut self, mut size: Size, mut format: impl Into) { + fn init(&mut self, mut size: Size, format: impl Into) { self.format = format.into(); self.size = size; @@ -133,7 +140,13 @@ impl Framebuffer { // reset the framebuffer image if self.image != 0 { - gl::FramebufferTexture2D(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, 0, 0); + gl::FramebufferTexture2D( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + gl::TEXTURE_2D, + 0, + 0, + ); gl::DeleteTextures(1, &self.image); } @@ -155,9 +168,20 @@ impl Framebuffer { self.levels = 1; } - gl::TexStorage2D(gl::TEXTURE_2D, self.levels as GLsizei, self.format, size.width as GLsizei, size.height as GLsizei); - gl::FramebufferTexture2D(gl::FRAMEBUFFER, - gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, self.image, 0); + gl::TexStorage2D( + gl::TEXTURE_2D, + self.levels as GLsizei, + self.format, + size.width as GLsizei, + size.height as GLsizei, + ); + gl::FramebufferTexture2D( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + gl::TEXTURE_2D, + self.image, + 0, + ); let status = gl::CheckFramebufferStatus(gl::FRAMEBUFFER); if status != gl::FRAMEBUFFER_COMPLETE { @@ -165,8 +189,13 @@ impl Framebuffer { gl::FRAMEBUFFER_UNSUPPORTED => { eprintln!("unsupported fbo"); - gl::FramebufferTexture2D(gl::FRAMEBUFFER, - gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, 0, 0); + gl::FramebufferTexture2D( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + gl::TEXTURE_2D, + 0, + 0, + ); gl::DeleteTextures(1, &self.image); gl::GenTextures(1, &mut self.image); gl::BindTexture(1, self.image); @@ -179,12 +208,24 @@ impl Framebuffer { self.levels = 1; } - gl::TexStorage2D(gl::TEXTURE_2D, self.levels as GLsizei, ShaderFormat::R8G8B8A8Unorm.into(), size.width as GLsizei, size.height as GLsizei); - gl::FramebufferTexture2D(gl::FRAMEBUFFER, - gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, self.image, 0); - self.init = gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE; + gl::TexStorage2D( + gl::TEXTURE_2D, + self.levels as GLsizei, + ShaderFormat::R8G8B8A8Unorm.into(), + size.width as GLsizei, + size.height as GLsizei, + ); + gl::FramebufferTexture2D( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + gl::TEXTURE_2D, + self.image, + 0, + ); + self.init = + gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE; } - _ => panic!("failed to complete: {status:x}") + _ => panic!("failed to complete: {status:x}"), } } else { self.init = true; @@ -207,4 +248,4 @@ impl Drop for Framebuffer { } } } -} \ No newline at end of file +} diff --git a/librashader-runtime-gl/src/hello_triangle.rs b/librashader-runtime-gl/src/hello_triangle.rs index b0ba899..7a04b07 100644 --- a/librashader-runtime-gl/src/hello_triangle.rs +++ b/librashader-runtime-gl/src/hello_triangle.rs @@ -2,11 +2,10 @@ use std::convert::TryInto; use std::ffi::{c_void, CStr}; use std::sync::mpsc::Receiver; -use glfw; use glfw::{Context, Glfw, Window, WindowEvent}; -use gl; + use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint}; -use glfw::Key::P; + use crate::filter_chain::FilterChain; use crate::framebuffer::Framebuffer; use crate::util::{GlImage, Size, Viewport}; @@ -18,7 +17,12 @@ const TITLE: &str = "Hello From OpenGL World!"; pub fn compile_program(vertex: &str, fragment: &str) -> GLuint { let vertex_shader = unsafe { gl::CreateShader(gl::VERTEX_SHADER) }; unsafe { - gl::ShaderSource(vertex_shader, 1, &vertex.as_bytes().as_ptr().cast(), &vertex.len().try_into().unwrap()); + gl::ShaderSource( + vertex_shader, + 1, + &vertex.as_bytes().as_ptr().cast(), + &vertex.len().try_into().unwrap(), + ); gl::CompileShader(vertex_shader); let mut success = 0; @@ -31,13 +35,21 @@ pub fn compile_program(vertex: &str, fragment: &str) -> GLuint { let mut v: Vec = Vec::with_capacity(1024); gl::GetShaderInfoLog(vertex_shader, 1024, &mut log_len, v.as_mut_ptr().cast()); v.set_len(log_len.try_into().unwrap()); - panic!("Vertex Shader Compile Error: {}", String::from_utf8_lossy(&v)); + panic!( + "Vertex Shader Compile Error: {}", + String::from_utf8_lossy(&v) + ); } } let fragment_shader = unsafe { gl::CreateShader(gl::FRAGMENT_SHADER) }; unsafe { - gl::ShaderSource(fragment_shader, 1, &fragment.as_bytes().as_ptr().cast(), &fragment.len().try_into().unwrap()); + gl::ShaderSource( + fragment_shader, + 1, + &fragment.as_bytes().as_ptr().cast(), + &fragment.len().try_into().unwrap(), + ); gl::CompileShader(fragment_shader); let mut success = 0; @@ -47,7 +59,10 @@ pub fn compile_program(vertex: &str, fragment: &str) -> GLuint { let mut log_len = 0_i32; gl::GetShaderInfoLog(fragment_shader, 1024, &mut log_len, v.as_mut_ptr().cast()); v.set_len(log_len.try_into().unwrap()); - panic!("Fragment Shader Compile Error: {}", String::from_utf8_lossy(&v)); + panic!( + "Fragment Shader Compile Error: {}", + String::from_utf8_lossy(&v) + ); } } @@ -76,39 +91,53 @@ pub fn compile_program(vertex: &str, fragment: &str) -> GLuint { shader_program } - -extern "system" fn debug_callback(source: GLenum, err_type: GLenum, id: GLuint, severity: GLenum, length: GLsizei, message: *const GLchar, _user: *mut c_void) { +extern "system" fn debug_callback( + _source: GLenum, + _err_type: GLenum, + _id: GLuint, + _severity: GLenum, + _length: GLsizei, + message: *const GLchar, + _user: *mut c_void, +) { unsafe { let message = CStr::from_ptr(message); - eprintln!("{:?}", message); + eprintln!("{message:?}"); } } pub fn setup() -> (Glfw, Window, Receiver<(f64, WindowEvent)>, GLuint, GLuint) { let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3)); - glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core)); + glfw.window_hint(glfw::WindowHint::OpenGlProfile( + glfw::OpenGlProfileHint::Core, + )); glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); glfw.window_hint(glfw::WindowHint::Resizable(false)); glfw.window_hint(glfw::WindowHint::OpenGlDebugContext(true)); - let (mut window, events) = glfw.create_window(WIDTH, HEIGHT, TITLE, glfw::WindowMode::Windowed).unwrap(); + let (mut window, events) = glfw + .create_window(WIDTH, HEIGHT, TITLE, glfw::WindowMode::Windowed) + .unwrap(); let (screen_width, screen_height) = window.get_framebuffer_size(); window.make_current(); window.set_key_polling(true); gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); - unsafe { gl::Enable(gl::DEBUG_OUTPUT); gl::Enable(gl::DEBUG_OUTPUT_SYNCHRONOUS); gl::DebugMessageCallback(Some(debug_callback), std::ptr::null_mut()); - gl::DebugMessageControl(gl::DONT_CARE, - gl::DONT_CARE, - gl::DONT_CARE, - 0, std::ptr::null(), gl::TRUE); + gl::DebugMessageControl( + gl::DONT_CARE, + gl::DONT_CARE, + gl::DONT_CARE, + 0, + std::ptr::null(), + gl::TRUE, + ); } unsafe { @@ -147,20 +176,24 @@ void main() let shader_program = compile_program(VERT_SHADER, FRAG_SHADER); unsafe { - gl::ObjectLabel(gl::SHADER, shader_program, -1, b"color_shader\0".as_ptr().cast()); + gl::ObjectLabel( + gl::SHADER, + shader_program, + -1, + b"color_shader\0".as_ptr().cast(), + ); } let vertices = &[ // positions // colors - 0.5f32, -0.5, 0.0, 1.0, 0.0, 0.0, // bottom right - -0.5, -0.5, 0.0, 0.0, 1.0, 0.0, // bottom left - 0.0, 0.5, 0.0, 0.0, 0.0, 1.0 // top + 0.5f32, -0.5, 0.0, 1.0, 0.0, 0.0, // bottom right + -0.5, -0.5, 0.0, 0.0, 1.0, 0.0, // bottom left + 0.0, 0.5, 0.0, 0.0, 0.0, 1.0, // top ]; let mut vbo: gl::types::GLuint = 0; unsafe { gl::GenBuffers(1, &mut vbo); gl::ObjectLabel(gl::BUFFER, vbo, -1, b"triangle_vbo\0".as_ptr().cast()); - } unsafe { @@ -180,7 +213,6 @@ void main() unsafe { gl::GenVertexArrays(1, &mut vao); gl::ObjectLabel(gl::VERTEX_ARRAY, vao, -1, b"triangle_vao\0".as_ptr().cast()); - } unsafe { @@ -217,15 +249,24 @@ void main() gl::ClearColor(0.3, 0.3, 0.5, 1.0); } - // ------------------------------------------- println!("OpenGL version: {}", gl_get_string(gl::VERSION)); - println!("GLSL version: {}", gl_get_string(gl::SHADING_LANGUAGE_VERSION)); + println!( + "GLSL version: {}", + gl_get_string(gl::SHADING_LANGUAGE_VERSION) + ); (glfw, window, events, shader_program, vao) } -pub fn do_loop(mut glfw: Glfw, mut window: Window, events: Receiver<(f64, WindowEvent)>, triangle_program: GLuint, triangle_vao: GLuint, filter: &mut FilterChain) { +pub fn do_loop( + mut glfw: Glfw, + mut window: Window, + events: Receiver<(f64, WindowEvent)>, + triangle_program: GLuint, + triangle_vao: GLuint, + filter: &mut FilterChain, +) { let mut rendered_framebuffer = 0; let mut rendered_texture = 0; let mut quad_vbuf = 0; @@ -239,24 +280,54 @@ pub fn do_loop(mut glfw: Glfw, mut window: Window, events: Receiver<(f64, Window gl::GenFramebuffers(1, &mut rendered_framebuffer); gl::BindFramebuffer(gl::FRAMEBUFFER, rendered_framebuffer); - gl::ObjectLabel(gl::FRAMEBUFFER, rendered_framebuffer, -1, b"rendered_framebuffer\0".as_ptr().cast()); + gl::ObjectLabel( + gl::FRAMEBUFFER, + rendered_framebuffer, + -1, + b"rendered_framebuffer\0".as_ptr().cast(), + ); // make tetxure gl::GenTextures(1, &mut rendered_texture); gl::BindTexture(gl::TEXTURE_2D, rendered_texture); - gl::ObjectLabel(gl::TEXTURE, rendered_texture, -1, b"rendered_texture\0".as_ptr().cast()); + gl::ObjectLabel( + gl::TEXTURE, + rendered_texture, + -1, + b"rendered_texture\0".as_ptr().cast(), + ); // empty image - gl::TexStorage2D(gl::TEXTURE_2D, 1, gl::RGBA8, WIDTH as GLsizei, HEIGHT as GLsizei); + gl::TexStorage2D( + gl::TEXTURE_2D, + 1, + gl::RGBA8, + WIDTH as GLsizei, + HEIGHT as GLsizei, + ); 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); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as GLint); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as GLint); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_S, + gl::CLAMP_TO_EDGE as GLint, + ); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_T, + gl::CLAMP_TO_EDGE as GLint, + ); // set color attachment - gl::FramebufferTexture2D(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, rendered_texture, 0); + gl::FramebufferTexture2D( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + gl::TEXTURE_2D, + rendered_texture, + 0, + ); let buffers = [gl::COLOR_ATTACHMENT0]; gl::DrawBuffers(1, buffers.as_ptr()); @@ -266,21 +337,17 @@ pub fn do_loop(mut glfw: Glfw, mut window: Window, events: Receiver<(f64, Window } let fullscreen_fbo = [ - -1.0f32, -1.0, 0.0, - 1.0, -1.0, 0.0, - -1.0, 1.0, 0.0, - -1.0, 1.0, 0.0, - 1.0, -1.0, 0.0, - 1.0, 1.0, 0.0, + -1.0f32, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, + 1.0, 1.0, 0.0, ]; gl::GenBuffers(1, &mut quad_vbuf); gl::BindBuffer(gl::ARRAY_BUFFER, quad_vbuf); gl::BufferData( - gl::ARRAY_BUFFER, // target + gl::ARRAY_BUFFER, // target (fullscreen_fbo.len() * std::mem::size_of::()) as gl::types::GLsizeiptr, // size of data in bytes fullscreen_fbo.as_ptr() as *const gl::types::GLvoid, // pointer to data - gl::STATIC_DRAW, // usage + gl::STATIC_DRAW, // usage ); } @@ -289,24 +356,54 @@ pub fn do_loop(mut glfw: Glfw, mut window: Window, events: Receiver<(f64, Window gl::GenFramebuffers(1, &mut output_framebuffer_handle); gl::BindFramebuffer(gl::FRAMEBUFFER, output_framebuffer_handle); - gl::ObjectLabel(gl::FRAMEBUFFER, output_framebuffer_handle, -1, b"output_framebuffer\0".as_ptr().cast()); + gl::ObjectLabel( + gl::FRAMEBUFFER, + output_framebuffer_handle, + -1, + b"output_framebuffer\0".as_ptr().cast(), + ); // make tetxure gl::GenTextures(1, &mut output_texture); gl::BindTexture(gl::TEXTURE_2D, output_texture); - gl::ObjectLabel(gl::TEXTURE, output_texture, -1, b"output_texture\0".as_ptr().cast()); + gl::ObjectLabel( + gl::TEXTURE, + output_texture, + -1, + b"output_texture\0".as_ptr().cast(), + ); // empty image - gl::TexStorage2D(gl::TEXTURE_2D, 1, gl::RGBA8, WIDTH as GLsizei, HEIGHT as GLsizei); + gl::TexStorage2D( + gl::TEXTURE_2D, + 1, + gl::RGBA8, + WIDTH as GLsizei, + HEIGHT as GLsizei, + ); 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); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as GLint); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as GLint); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_S, + gl::CLAMP_TO_EDGE as GLint, + ); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_T, + gl::CLAMP_TO_EDGE as GLint, + ); // set color attachment - gl::FramebufferTexture2D(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, output_texture, 0); + gl::FramebufferTexture2D( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + gl::TEXTURE_2D, + output_texture, + 0, + ); let buffers = [gl::COLOR_ATTACHMENT0]; gl::DrawBuffers(1, buffers.as_ptr()); @@ -316,21 +413,17 @@ pub fn do_loop(mut glfw: Glfw, mut window: Window, events: Receiver<(f64, Window } let fullscreen_fbo = [ - -1.0f32, -1.0, 0.0, - 1.0, -1.0, 0.0, - -1.0, 1.0, 0.0, - -1.0, 1.0, 0.0, - 1.0, -1.0, 0.0, - 1.0, 1.0, 0.0, + -1.0f32, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, + 1.0, 1.0, 0.0, ]; gl::GenBuffers(1, &mut output_quad_vbuf); gl::BindBuffer(gl::ARRAY_BUFFER, output_quad_vbuf); gl::BufferData( - gl::ARRAY_BUFFER, // target + gl::ARRAY_BUFFER, // target (fullscreen_fbo.len() * std::mem::size_of::()) as gl::types::GLsizeiptr, // size of data in bytes fullscreen_fbo.as_ptr() as *const gl::types::GLvoid, // pointer to data - gl::STATIC_DRAW, // usage + gl::STATIC_DRAW, // usage ); } @@ -359,17 +452,22 @@ void main() color=texture(texSampler, v_tex); }"; - let quad_programid = compile_program(VERT_SHADER, FRAG_SHADER); let mut quad_vao = 0; unsafe { gl::GenVertexArrays(1, &mut quad_vao); } - let fb = Framebuffer::new_from_raw(output_texture, output_framebuffer_handle, gl::RGBA8, Size { - width: WIDTH, - height: HEIGHT - }, 1); + let fb = Framebuffer::new_from_raw( + output_texture, + output_framebuffer_handle, + gl::RGBA8, + Size { + width: WIDTH, + height: HEIGHT, + }, + 1, + ); while !window.should_close() { glfw.poll_events(); @@ -382,14 +480,12 @@ void main() gl::BindFramebuffer(gl::FRAMEBUFFER, rendered_framebuffer); // gl::BindFramebuffer(gl::FRAMEBUFFER, 0); - gl::Viewport(0, 0, WIDTH as GLsizei, HEIGHT as GLsizei); // clear color clear_color(Color(0.3, 0.4, 0.6, 1.0)); gl::Clear(gl::COLOR_BUFFER_BIT); - // do the drawing gl::UseProgram(triangle_program); // select vertices @@ -403,7 +499,6 @@ void main() // unselect fbo gl::BindFramebuffer(gl::FRAMEBUFFER, 0); - } // eprintln!("[core] rendered texture is {rendered_texture}"); @@ -415,20 +510,25 @@ void main() // gl::BindTexture(gl::TEXTURE_2D, rendered_texture); // } unsafe { - filter.frame(0, &Viewport { - x: 0, - y: 0, - output: &fb, - mvp: None - }, GlImage { - handle: rendered_texture, - format: gl::RGBA8, - size: Size { - width: WIDTH, - height: HEIGHT + filter.frame( + 0, + &Viewport { + x: 0, + y: 0, + output: &fb, + mvp: None, }, - padded_size: Default::default() - }, false) + GlImage { + handle: rendered_texture, + format: gl::RGBA8, + size: Size { + width: WIDTH, + height: HEIGHT, + }, + padded_size: Default::default(), + }, + false, + ) } unsafe { @@ -440,8 +540,6 @@ void main() gl::BindFramebuffer(gl::FRAMEBUFFER, 0); gl::UseProgram(quad_programid); - - gl::ActiveTexture(gl::TEXTURE0); gl::BindTexture(gl::TEXTURE_2D, output_texture); @@ -467,14 +565,14 @@ pub fn gl_get_string<'a>(name: gl::types::GLenum) -> &'a str { } fn glfw_handle_event(window: &mut glfw::Window, event: glfw::WindowEvent) { - use glfw::WindowEvent as Event; - use glfw::Key; use glfw::Action; + use glfw::Key; + use glfw::WindowEvent as Event; match event { Event::Key(Key::Escape, _, Action::Press, _) => { window.set_should_close(true); - }, - _ => {}, + } + _ => {} } -} \ No newline at end of file +} diff --git a/librashader-runtime-gl/src/lib.rs b/librashader-runtime-gl/src/lib.rs index 69cdfd1..8d8cc4f 100644 --- a/librashader-runtime-gl/src/lib.rs +++ b/librashader-runtime-gl/src/lib.rs @@ -1,28 +1,26 @@ #![feature(strict_provenance)] -mod hello_triangle; -mod filter_pass; -mod util; -mod framebuffer; mod binding; mod filter_chain; +mod filter_pass; +mod framebuffer; +mod hello_triangle; mod render_target; - +mod util; #[cfg(test)] mod tests { - use crate::filter_chain::FilterChain; use super::*; + use crate::filter_chain::FilterChain; #[test] fn triangle() { let (glfw, window, events, shader, vao) = hello_triangle::setup(); let mut filter = FilterChain::load("../test/basic.slangp").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] diff --git a/librashader-runtime-gl/src/render_target.rs b/librashader-runtime-gl/src/render_target.rs index d5479df..203e84e 100644 --- a/librashader-runtime-gl/src/render_target.rs +++ b/librashader-runtime-gl/src/render_target.rs @@ -2,36 +2,33 @@ use crate::framebuffer::Framebuffer; use crate::util::Viewport; static DEFAULT_MVP: &[f32] = &[ - 2f32, 0.0, 0.0, 0.0, - 0.0, 2.0, 0.0, 0.0, - 0.0, 0.0, 2.0, 0.0, - -1.0, -1.0, 0.0, 1.0 + 2f32, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, -1.0, -1.0, 0.0, 1.0, ]; #[derive(Debug, Copy, Clone)] pub struct RenderTarget<'a> { pub mvp: &'a [f32], - pub framebuffer: &'a Framebuffer + pub framebuffer: &'a Framebuffer, } -impl <'a> RenderTarget<'a> { +impl<'a> RenderTarget<'a> { pub fn new(backbuffer: &'a Framebuffer, mvp: Option<&'a [f32]>) -> Self { if let Some(mvp) = mvp { RenderTarget { framebuffer: backbuffer, - mvp + mvp, } } else { RenderTarget { framebuffer: backbuffer, - mvp: DEFAULT_MVP + mvp: DEFAULT_MVP, } } } } -impl <'a> From<&Viewport<'a>> for RenderTarget<'a> { +impl<'a> From<&Viewport<'a>> for RenderTarget<'a> { fn from(value: &Viewport<'a>) -> Self { RenderTarget::new(value.output, value.mvp) } -} \ No newline at end of file +} diff --git a/librashader-runtime-gl/src/util.rs b/librashader-runtime-gl/src/util.rs index 512778e..eab2ed6 100644 --- a/librashader-runtime-gl/src/util.rs +++ b/librashader-runtime-gl/src/util.rs @@ -1,6 +1,6 @@ -use gl::types::{GLenum, GLint, GLuint}; -use librashader::{FilterMode, WrapMode}; use crate::framebuffer::Framebuffer; +use gl::types::{GLenum, GLuint}; +use librashader::{FilterMode, WrapMode}; pub fn calc_miplevel(width: u32, height: u32) -> u32 { let mut size = std::cmp::max(width, height); @@ -10,7 +10,7 @@ pub fn calc_miplevel(width: u32, height: u32) -> u32 { size >>= 1; } - return levels; + levels } #[derive(Debug, Copy, Clone)] @@ -18,7 +18,7 @@ pub struct Texture { pub image: GlImage, pub filter: FilterMode, pub mip_filter: FilterMode, - pub wrap_mode: WrapMode + pub wrap_mode: WrapMode, } #[derive(Debug, Copy, Clone)] @@ -26,7 +26,7 @@ pub struct Viewport<'a> { pub x: i32, pub y: i32, pub output: &'a Framebuffer, - pub mvp: Option<&'a [f32]> + pub mvp: Option<&'a [f32]>, } #[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] @@ -40,10 +40,10 @@ pub struct GlImage { pub handle: GLuint, pub format: GLenum, pub size: Size, - pub padded_size: Size + pub padded_size: Size, } -impl RingBuffer { +impl RingBuffer { pub fn current(&self) -> &T { &self.items[self.index] } @@ -58,16 +58,18 @@ impl RingBuffer { pub struct RingBuffer { items: [T; SIZE], - index: usize + index: usize, } -impl RingBuffer -where T: Copy, T: Default +impl RingBuffer +where + T: Copy, + T: Default, { pub fn new() -> Self { Self { items: [T::default(); SIZE], - index: 0 + index: 0, } } @@ -82,7 +84,12 @@ where T: Copy, T: Default pub unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> GLuint { let shader = gl::CreateShader(stage); - gl::ShaderSource(shader, 1, &source.as_bytes().as_ptr().cast(), std::ptr::null()); + gl::ShaderSource( + shader, + 1, + &source.as_bytes().as_ptr().cast(), + std::ptr::null(), + ); gl::CompileShader(shader); let mut compile_status = 0; gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut compile_status);