From c06751eca9a6f7da77d4c7792ec70eb06576776e Mon Sep 17 00:00:00 2001 From: chyyran Date: Thu, 17 Nov 2022 00:08:11 -0500 Subject: [PATCH] gl: load luts --- Cargo.lock | 295 +++++++++++++++++++++- librashader-runtime-gl/src/filter_pass.rs | 84 +++++- librashader-runtime-gl/src/lib.rs | 94 ++++++- librashader-runtime-gl/src/util.rs | 8 +- librashader/Cargo.toml | 3 +- librashader/src/gl.rs | 21 ++ librashader/src/image.rs | 23 ++ librashader/src/lib.rs | 5 +- 8 files changed, 509 insertions(+), 24 deletions(-) create mode 100644 librashader/src/image.rs diff --git a/Cargo.lock b/Cargo.lock index e50c624..bb6432e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aho-corasick" version = "0.7.19" @@ -67,6 +73,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + [[package]] name = "bitflags" version = "1.3.2" @@ -160,6 +172,21 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "criterion" version = "0.3.6" @@ -239,6 +266,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "csv" version = "1.1.6" @@ -303,12 +336,62 @@ dependencies = [ "termcolor", ] +[[package]] +name = "exr" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded" +dependencies = [ + "bit_field", + "flume", + "half 2.1.0", + "lebe", + "miniz_oxide 0.6.2", + "smallvec", + "threadpool", +] + [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +dependencies = [ + "crc32fast", + "miniz_oxide 0.5.4", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + [[package]] name = "fxhash" version = "0.2.1" @@ -318,6 +401,29 @@ dependencies = [ "byteorder", ] +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gl" version = "0.14.0" @@ -366,6 +472,15 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "half" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554" +dependencies = [ + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -393,6 +508,25 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + [[package]] name = "indexmap" version = "1.9.1" @@ -434,6 +568,15 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" version = "0.3.60" @@ -455,6 +598,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.135" @@ -466,6 +615,7 @@ name = "librashader" version = "0.1.0" dependencies = [ "gl", + "image", ] [[package]] @@ -529,6 +679,16 @@ dependencies = [ "spirv_cross", ] +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.17" @@ -568,6 +728,24 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +dependencies = [ + "adler", +] + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "naga" version = "0.10.0" @@ -596,6 +774,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + [[package]] name = "nom" version = "7.1.1" @@ -617,6 +804,27 @@ dependencies = [ "nom", ] +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -667,6 +875,26 @@ dependencies = [ "indexmap", ] +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "plotters" version = "0.3.4" @@ -695,6 +923,18 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "png" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide 0.6.2", +] + [[package]] name = "pp-rs" version = "0.2.1" @@ -839,6 +1079,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + [[package]] name = "scopeguard" version = "1.1.0" @@ -860,7 +1106,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ - "half", + "half 1.8.2", "serde", ] @@ -907,6 +1153,21 @@ dependencies = [ "roxmltree", ] +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + [[package]] name = "spirv" version = "0.2.0+1.5.4" @@ -978,6 +1239,26 @@ dependencies = [ "syn", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17def29300a156c19ae30814710d9c63cd50288a49c6fd3a10ccfbe4cf886fd" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -1017,6 +1298,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.83" @@ -1081,6 +1368,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + [[package]] name = "winapi" version = "0.3.9" diff --git a/librashader-runtime-gl/src/filter_pass.rs b/librashader-runtime-gl/src/filter_pass.rs index ae5a937..50f4f2f 100644 --- a/librashader-runtime-gl/src/filter_pass.rs +++ b/librashader-runtime-gl/src/filter_pass.rs @@ -1,14 +1,17 @@ use std::iter::Filter; -use gl::types::{GLint, GLuint}; +use gl::types::{GLenum, GLint, 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_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureSemantics, VariableMeta, VariableSemantics}; +use librashader::ShaderSource; +use librashader_presets::ShaderPreset; +use librashader_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureImage, TextureSemantics, VariableMeta, VariableSemantics}; +use crate::FilterChain; use crate::framebuffer::Framebuffer; -use crate::util::{Location, VariableLocation, RingBuffer, Size, Texture}; +use crate::util::{Location, VariableLocation, RingBuffer, Size, Texture, TextureMeta}; pub struct FilterPass { pub reflection: ShaderReflection, @@ -21,7 +24,7 @@ pub struct FilterPass { pub locations: FxHashMap, pub framebuffer: Framebuffer, pub feedback_framebuffer: Framebuffer, - + pub source: ShaderSource, } impl FilterPass { @@ -78,10 +81,21 @@ impl FilterPass { Self::build_uniform(location, buffer, value, gl::Uniform1f) } + fn set_texture(binding: &TextureImage, texture: &TextureMeta) { + unsafe { + gl::ActiveTexture((gl::TEXTURE0 + binding.binding) as GLenum); + gl::BindTexture(gl::TEXTURE_2D, texture.texture.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); + } + } // todo: build vec4 texture // framecount should be pre-modded - fn build_semantics(&mut self, mvp: Option<&[f32]>, frame_count: u32, frame_direction: u32, fb_size: Size, vp_size: Size, original: &Texture, source: &Texture) { + fn build_semantics(&mut self, parent: &FilterChain, mvp: Option<&[f32]>, frame_count: u32, frame_direction: u32, fb_size: Size, vp_size: Size, original: &TextureMeta, source: &TextureMeta) { if let Some(variable) = self.reflection.meta.variable_meta.get(&VariableSemantics::MVP) { let mvp = mvp.unwrap_or(&[ 2f32, 0.0, 0.0, 0.0, @@ -149,6 +163,66 @@ impl FilterPass { FilterPass::build_uint(location, &mut buffer[offset..][..4], frame_direction) } + if let Some(variable) = self.reflection.meta.texture_size_meta.get(&TextureSemantics::Original.semantics(0)) { + let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location(); + let (buffer, offset) = match variable.offset { + MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset), + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset) + }; + FilterPass::build_vec4(location, &mut buffer[offset..][..4], original.texture.size); + + if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::Original.semantics(0)) { + FilterPass::set_texture(binding, original); + } + } + + if let Some(variable) = self.reflection.meta.texture_size_meta.get(&TextureSemantics::Source.semantics(0)) { + let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location(); + let (buffer, offset) = match variable.offset { + MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset), + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset) + }; + FilterPass::build_vec4(location, &mut buffer[offset..][..4], original.texture.size); + + if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::Source.semantics(0)) { + FilterPass::set_texture(binding, original); + } + } + + if let Some(variable) = self.reflection.meta.texture_size_meta.get(&TextureSemantics::OriginalHistory.semantics(0)) { + let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location(); + let (buffer, offset) = match variable.offset { + MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset), + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset) + }; + FilterPass::build_vec4(location, &mut buffer[offset..][..4], original.texture.size); + + if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::OriginalHistory.semantics(0)) { + FilterPass::set_texture(binding, original); + } + } + + for variable in self.reflection.meta.parameter_meta.values() { + let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location(); + let (buffer, offset) = match variable.offset { + MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset), + MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset) + }; + + // presets override params + let default = self.source.parameters.iter().find(|&p| p.id == variable.id) + .map(|f| f.initial) + .unwrap_or(0f32); + + let value = parent.preset.parameters.iter().find(|&p| p.name == variable.id) + .map(|p| p.value) + .unwrap_or(default); + + FilterPass::build_float(location, &mut buffer[offset..][..4], value) + } + + // todo history + } } \ No newline at end of file diff --git a/librashader-runtime-gl/src/lib.rs b/librashader-runtime-gl/src/lib.rs index 61c0bdc..46b3dce 100644 --- a/librashader-runtime-gl/src/lib.rs +++ b/librashader-runtime-gl/src/lib.rs @@ -16,6 +16,7 @@ use filter_pass::FilterPass; use framebuffer::Framebuffer; use librashader::{FilterMode, ShaderFormat, ShaderSource, WrapMode}; +use librashader::image::Image; use librashader_presets::{ShaderPassConfig, ShaderPreset}; use librashader_reflect::back::{CompileShader, ShaderCompilerOutput}; use librashader_reflect::back::cross::{GlslangGlslContext, GlVersion}; @@ -116,11 +117,11 @@ pub struct FilterChain { semantics: ReflectSemantics, preset: ShaderPreset, original_history: Vec, - history: Vec, - feedback: Vec + history: Vec, + feedback: Vec, + luts: FxHashMap } - impl FilterChain { pub fn load(path: impl AsRef) -> Result> { let preset = librashader_presets::ShaderPreset::try_parse(path)?; @@ -273,11 +274,11 @@ impl FilterChain { uniform_buffer, push_buffer, locations, - + source, // no idea if this works. // retroarch checks if feedback frames are used but we'll just init it tbh. framebuffer: Framebuffer::new(1), - feedback_framebuffer: Framebuffer::new(1) + feedback_framebuffer: Framebuffer::new(1), }); } @@ -287,7 +288,7 @@ impl FilterChain { // // compilation.context.compiler.vertex // } -// eprintln!("{:#?}", reflections); + // eprintln!("{:#?}", reflections); // eprintln!("{:#?}", compiled./); // eprintln!("{:?}", preset); @@ -301,13 +302,84 @@ impl FilterChain { // gl3.cpp: 1942 + // load luts + let mut luts = FxHashMap::default(); + + for texture in &preset.textures { + 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(texture.name.clone(), TextureMeta { + texture: Texture { + 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(FilterChain { passes: filters, semantics, preset, original_history: vec![], history: vec![], - feedback: vec![] + feedback: vec![], + luts, }) } @@ -333,8 +405,8 @@ impl FilterChain { // todo: get filter info from pass data. let original = TextureMeta { texture: input, - filter: gl::LINEAR, - mip_filter: gl::LINEAR_MIPMAP_LINEAR, + filter: FilterMode::Linear, + mip_filter: FilterMode::Linear, wrap_mode: Default::default() }; @@ -351,8 +423,8 @@ mod tests { #[test] fn triangle() { let (glfw, window, events, shader, vao) = hello_triangle::setup(); - FilterChain::load("../test/basic.slangp").unwrap(); - // FilterChain::load("../test/slang-shaders/crt/crt-royale.slangp").unwrap(); + // 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); } diff --git a/librashader-runtime-gl/src/util.rs b/librashader-runtime-gl/src/util.rs index 62c7327..bd346ee 100644 --- a/librashader-runtime-gl/src/util.rs +++ b/librashader-runtime-gl/src/util.rs @@ -1,5 +1,5 @@ use gl::types::{GLenum, GLint, GLuint}; -use librashader::WrapMode; +use librashader::{FilterMode, WrapMode}; #[derive(Debug, Copy, Clone)] pub struct Location { @@ -34,8 +34,8 @@ pub fn calc_miplevel(width: u32, height: u32) -> u32 { pub struct TextureMeta { pub texture: Texture, - pub filter: GLenum, - pub mip_filter: GLenum, + pub filter: FilterMode, + pub mip_filter: FilterMode, pub wrap_mode: WrapMode } @@ -47,7 +47,7 @@ pub struct Viewport { pub height: i32 } -#[derive(Debug, Copy, Clone)] +#[derive(Default, Debug, Copy, Clone)] pub struct Size { pub width: u32, pub height: u32, diff --git a/librashader/Cargo.toml b/librashader/Cargo.toml index 04d679f..6b99c62 100644 --- a/librashader/Cargo.toml +++ b/librashader/Cargo.toml @@ -10,4 +10,5 @@ default = [ "opengl" ] opengl = ["gl"] [dependencies] -gl = { version = "0.14.0", optional = true } \ No newline at end of file +gl = { version = "0.14.0", optional = true } +image = "0.24.5" \ No newline at end of file diff --git a/librashader/src/gl.rs b/librashader/src/gl.rs index 236ef02..8ab6a8f 100644 --- a/librashader/src/gl.rs +++ b/librashader/src/gl.rs @@ -1,3 +1,4 @@ +use gl::types::GLenum; use crate::{FilterMode, ShaderFormat, WrapMode}; impl From for gl::types::GLenum { @@ -48,3 +49,23 @@ impl From for gl::types::GLenum { } } } + +impl From for gl::types::GLenum { + fn from(value: FilterMode) -> Self { + match value { + FilterMode::Linear => gl::LINEAR, + _ => gl::NEAREST + } + } +} + +impl FilterMode { + pub fn gl_mip(&self, mip: FilterMode) -> gl::types::GLenum { + match (self, mip) { + (FilterMode::Linear, FilterMode::Linear) => gl::LINEAR_MIPMAP_LINEAR, + (FilterMode::Linear, FilterMode::Nearest) => gl::LINEAR_MIPMAP_NEAREST, + (FilterMode::Nearest, FilterMode::Linear) => gl::NEAREST_MIPMAP_LINEAR, + _ => gl::NEAREST_MIPMAP_NEAREST + } + } +} \ No newline at end of file diff --git a/librashader/src/image.rs b/librashader/src/image.rs new file mode 100644 index 0000000..2b3dbfe --- /dev/null +++ b/librashader/src/image.rs @@ -0,0 +1,23 @@ +use std::ffi::OsStr; +use std::io::ErrorKind; +use std::path::Path; + +pub struct Image { + pub bytes: Vec, + pub height: u32, + pub width: u32, +} + +impl Image { + pub fn load(path: impl AsRef) -> Result{ + let image = image::open(path.as_ref())?.to_rgba8(); + let height = image.height(); + let width = image.width(); + + Ok(Image { + bytes: image.to_vec(), + height, + width + }) + } +} \ No newline at end of file diff --git a/librashader/src/lib.rs b/librashader/src/lib.rs index 42d8358..8c18506 100644 --- a/librashader/src/lib.rs +++ b/librashader/src/lib.rs @@ -1,5 +1,6 @@ #[cfg(feature = "opengl")] pub mod gl; +pub mod image; use std::convert::Infallible; use std::str::FromStr; @@ -69,7 +70,7 @@ pub enum ShaderFormat { } #[repr(i32)] -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Eq, PartialEq)] pub enum FilterMode { #[default] Linear = 0, @@ -93,7 +94,7 @@ impl FromStr for WrapMode { #[repr(i32)] -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Eq, PartialEq)] pub enum WrapMode { #[default] ClampToBorder = 0,