gl: load luts

This commit is contained in:
chyyran 2022-11-17 00:08:11 -05:00
parent 888d7be50f
commit c06751eca9
8 changed files with 509 additions and 24 deletions

295
Cargo.lock generated
View file

@ -2,6 +2,12 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.19" version = "0.7.19"
@ -67,6 +73,12 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bit_field"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -160,6 +172,21 @@ dependencies = [
"unicode-width", "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]] [[package]]
name = "criterion" name = "criterion"
version = "0.3.6" version = "0.3.6"
@ -239,6 +266,12 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]] [[package]]
name = "csv" name = "csv"
version = "1.1.6" version = "1.1.6"
@ -303,12 +336,62 @@ dependencies = [
"termcolor", "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]] [[package]]
name = "fixedbitset" name = "fixedbitset"
version = "0.4.2" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 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]] [[package]]
name = "fxhash" name = "fxhash"
version = "0.2.1" version = "0.2.1"
@ -318,6 +401,29 @@ dependencies = [
"byteorder", "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]] [[package]]
name = "gl" name = "gl"
version = "0.14.0" version = "0.14.0"
@ -366,6 +472,15 @@ version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
[[package]]
name = "half"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554"
dependencies = [
"crunchy",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.3"
@ -393,6 +508,25 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 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]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.9.1" version = "1.9.1"
@ -434,6 +568,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "jpeg-decoder"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
dependencies = [
"rayon",
]
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.60" version = "0.3.60"
@ -455,6 +598,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lebe"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.135" version = "0.2.135"
@ -466,6 +615,7 @@ name = "librashader"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"gl", "gl",
"image",
] ]
[[package]] [[package]]
@ -529,6 +679,16 @@ dependencies = [
"spirv_cross", "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]] [[package]]
name = "log" name = "log"
version = "0.4.17" version = "0.4.17"
@ -568,6 +728,24 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 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]] [[package]]
name = "naga" name = "naga"
version = "0.10.0" version = "0.10.0"
@ -596,6 +774,15 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "nanorand"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
dependencies = [
"getrandom",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.1" version = "7.1.1"
@ -617,6 +804,27 @@ dependencies = [
"nom", "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]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.15" version = "0.2.15"
@ -667,6 +875,26 @@ dependencies = [
"indexmap", "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]] [[package]]
name = "plotters" name = "plotters"
version = "0.3.4" version = "0.3.4"
@ -695,6 +923,18 @@ dependencies = [
"plotters-backend", "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]] [[package]]
name = "pp-rs" name = "pp-rs"
version = "0.2.1" version = "0.2.1"
@ -839,6 +1079,12 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "scoped_threadpool"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.1.0" version = "1.1.0"
@ -860,7 +1106,7 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
dependencies = [ dependencies = [
"half", "half 1.8.2",
"serde", "serde",
] ]
@ -907,6 +1153,21 @@ dependencies = [
"roxmltree", "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]] [[package]]
name = "spirv" name = "spirv"
version = "0.2.0+1.5.4" version = "0.2.0+1.5.4"
@ -978,6 +1239,26 @@ dependencies = [
"syn", "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]] [[package]]
name = "tinytemplate" name = "tinytemplate"
version = "1.2.1" version = "1.2.1"
@ -1017,6 +1298,12 @@ dependencies = [
"winapi-util", "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]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.83" version = "0.2.83"
@ -1081,6 +1368,12 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "weezl"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

View file

@ -1,14 +1,17 @@
use std::iter::Filter; 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::cross::GlslangGlslContext;
use librashader_reflect::back::ShaderCompilerOutput; use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::ShaderReflection; use librashader_reflect::reflect::ShaderReflection;
use librashader_reflect::reflect::TextureSemanticMap; use librashader_reflect::reflect::TextureSemanticMap;
use librashader_reflect::reflect::VariableSemanticMap; use librashader_reflect::reflect::VariableSemanticMap;
use rustc_hash::FxHashMap; 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::framebuffer::Framebuffer;
use crate::util::{Location, VariableLocation, RingBuffer, Size, Texture}; use crate::util::{Location, VariableLocation, RingBuffer, Size, Texture, TextureMeta};
pub struct FilterPass { pub struct FilterPass {
pub reflection: ShaderReflection, pub reflection: ShaderReflection,
@ -21,7 +24,7 @@ pub struct FilterPass {
pub locations: FxHashMap<String, VariableLocation>, pub locations: FxHashMap<String, VariableLocation>,
pub framebuffer: Framebuffer, pub framebuffer: Framebuffer,
pub feedback_framebuffer: Framebuffer, pub feedback_framebuffer: Framebuffer,
pub source: ShaderSource,
} }
impl FilterPass { impl FilterPass {
@ -78,10 +81,21 @@ impl FilterPass {
Self::build_uniform(location, buffer, value, gl::Uniform1f) 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 // todo: build vec4 texture
// framecount should be pre-modded // 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) { if let Some(variable) = self.reflection.meta.variable_meta.get(&VariableSemantics::MVP) {
let mvp = mvp.unwrap_or(&[ let mvp = mvp.unwrap_or(&[
2f32, 0.0, 0.0, 0.0, 2f32, 0.0, 0.0, 0.0,
@ -149,6 +163,66 @@ impl FilterPass {
FilterPass::build_uint(location, &mut buffer[offset..][..4], frame_direction) 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
} }
} }

View file

@ -16,6 +16,7 @@ use filter_pass::FilterPass;
use framebuffer::Framebuffer; use framebuffer::Framebuffer;
use librashader::{FilterMode, ShaderFormat, ShaderSource, WrapMode}; use librashader::{FilterMode, ShaderFormat, ShaderSource, WrapMode};
use librashader::image::Image;
use librashader_presets::{ShaderPassConfig, ShaderPreset}; use librashader_presets::{ShaderPassConfig, ShaderPreset};
use librashader_reflect::back::{CompileShader, ShaderCompilerOutput}; use librashader_reflect::back::{CompileShader, ShaderCompilerOutput};
use librashader_reflect::back::cross::{GlslangGlslContext, GlVersion}; use librashader_reflect::back::cross::{GlslangGlslContext, GlVersion};
@ -116,11 +117,11 @@ pub struct FilterChain {
semantics: ReflectSemantics, semantics: ReflectSemantics,
preset: ShaderPreset, preset: ShaderPreset,
original_history: Vec<Framebuffer>, original_history: Vec<Framebuffer>,
history: Vec<Texture>, history: Vec<TextureMeta>,
feedback: Vec<Texture> feedback: Vec<TextureMeta>,
luts: FxHashMap<String, TextureMeta>
} }
impl FilterChain { impl FilterChain {
pub fn load(path: impl AsRef<Path>) -> Result<FilterChain, Box<dyn Error>> { pub fn load(path: impl AsRef<Path>) -> Result<FilterChain, Box<dyn Error>> {
let preset = librashader_presets::ShaderPreset::try_parse(path)?; let preset = librashader_presets::ShaderPreset::try_parse(path)?;
@ -273,11 +274,11 @@ impl FilterChain {
uniform_buffer, uniform_buffer,
push_buffer, push_buffer,
locations, locations,
source,
// no idea if this works. // no idea if this works.
// retroarch checks if feedback frames are used but we'll just init it tbh. // retroarch checks if feedback frames are used but we'll just init it tbh.
framebuffer: Framebuffer::new(1), framebuffer: Framebuffer::new(1),
feedback_framebuffer: Framebuffer::new(1) feedback_framebuffer: Framebuffer::new(1),
}); });
} }
@ -287,7 +288,7 @@ impl FilterChain {
// // compilation.context.compiler.vertex // // compilation.context.compiler.vertex
// } // }
// eprintln!("{:#?}", reflections); // eprintln!("{:#?}", reflections);
// eprintln!("{:#?}", compiled./); // eprintln!("{:#?}", compiled./);
// eprintln!("{:?}", preset); // eprintln!("{:?}", preset);
@ -301,13 +302,84 @@ impl FilterChain {
// gl3.cpp: 1942 // 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 { Ok(FilterChain {
passes: filters, passes: filters,
semantics, semantics,
preset, preset,
original_history: vec![], original_history: vec![],
history: vec![], history: vec![],
feedback: vec![] feedback: vec![],
luts,
}) })
} }
@ -333,8 +405,8 @@ impl FilterChain {
// todo: get filter info from pass data. // todo: get filter info from pass data.
let original = TextureMeta { let original = TextureMeta {
texture: input, texture: input,
filter: gl::LINEAR, filter: FilterMode::Linear,
mip_filter: gl::LINEAR_MIPMAP_LINEAR, mip_filter: FilterMode::Linear,
wrap_mode: Default::default() wrap_mode: Default::default()
}; };
@ -351,8 +423,8 @@ mod tests {
#[test] #[test]
fn triangle() { fn triangle() {
let (glfw, window, events, shader, vao) = hello_triangle::setup(); let (glfw, window, events, shader, vao) = hello_triangle::setup();
FilterChain::load("../test/basic.slangp").unwrap(); // FilterChain::load("../test/basic.slangp").unwrap();
// FilterChain::load("../test/slang-shaders/crt/crt-royale.slangp").unwrap(); FilterChain::load("../test/slang-shaders/crt/crt-royale.slangp").unwrap();
hello_triangle::do_loop(glfw, window, events, shader, vao); hello_triangle::do_loop(glfw, window, events, shader, vao);
} }

View file

@ -1,5 +1,5 @@
use gl::types::{GLenum, GLint, GLuint}; use gl::types::{GLenum, GLint, GLuint};
use librashader::WrapMode; use librashader::{FilterMode, WrapMode};
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Location<T> { pub struct Location<T> {
@ -34,8 +34,8 @@ pub fn calc_miplevel(width: u32, height: u32) -> u32 {
pub struct TextureMeta { pub struct TextureMeta {
pub texture: Texture, pub texture: Texture,
pub filter: GLenum, pub filter: FilterMode,
pub mip_filter: GLenum, pub mip_filter: FilterMode,
pub wrap_mode: WrapMode pub wrap_mode: WrapMode
} }
@ -47,7 +47,7 @@ pub struct Viewport {
pub height: i32 pub height: i32
} }
#[derive(Debug, Copy, Clone)] #[derive(Default, Debug, Copy, Clone)]
pub struct Size { pub struct Size {
pub width: u32, pub width: u32,
pub height: u32, pub height: u32,

View file

@ -11,3 +11,4 @@ opengl = ["gl"]
[dependencies] [dependencies]
gl = { version = "0.14.0", optional = true } gl = { version = "0.14.0", optional = true }
image = "0.24.5"

View file

@ -1,3 +1,4 @@
use gl::types::GLenum;
use crate::{FilterMode, ShaderFormat, WrapMode}; use crate::{FilterMode, ShaderFormat, WrapMode};
impl From<ShaderFormat> for gl::types::GLenum { impl From<ShaderFormat> for gl::types::GLenum {
@ -48,3 +49,23 @@ impl From<WrapMode> for gl::types::GLenum {
} }
} }
} }
impl From<FilterMode> 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
}
}
}

23
librashader/src/image.rs Normal file
View file

@ -0,0 +1,23 @@
use std::ffi::OsStr;
use std::io::ErrorKind;
use std::path::Path;
pub struct Image {
pub bytes: Vec<u8>,
pub height: u32,
pub width: u32,
}
impl Image {
pub fn load(path: impl AsRef<Path>) -> Result<Self, image::ImageError>{
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
})
}
}

View file

@ -1,5 +1,6 @@
#[cfg(feature = "opengl")] #[cfg(feature = "opengl")]
pub mod gl; pub mod gl;
pub mod image;
use std::convert::Infallible; use std::convert::Infallible;
use std::str::FromStr; use std::str::FromStr;
@ -69,7 +70,7 @@ pub enum ShaderFormat {
} }
#[repr(i32)] #[repr(i32)]
#[derive(Copy, Clone, Default, Debug)] #[derive(Copy, Clone, Default, Debug, Eq, PartialEq)]
pub enum FilterMode { pub enum FilterMode {
#[default] #[default]
Linear = 0, Linear = 0,
@ -93,7 +94,7 @@ impl FromStr for WrapMode {
#[repr(i32)] #[repr(i32)]
#[derive(Copy, Clone, Default, Debug)] #[derive(Copy, Clone, Default, Debug, Eq, PartialEq)]
pub enum WrapMode { pub enum WrapMode {
#[default] #[default]
ClampToBorder = 0, ClampToBorder = 0,