diff --git a/.idea/src.iml b/.idea/src.iml
index 276e6e4..abc9db7 100644
--- a/.idea/src.iml
+++ b/.idea/src.iml
@@ -5,6 +5,7 @@
+
diff --git a/Cargo.lock b/Cargo.lock
index 2897ffd..b0013ad 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,12 +2,115 @@
# It is not intended for manual editing.
version = 3
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bit-set"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
+dependencies = [
+ "bit-vec",
+]
+
+[[package]]
+name = "bit-vec"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bumpalo"
+version = "3.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+
[[package]]
name = "bytecount"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
+[[package]]
+name = "cc"
+version = "1.0.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+dependencies = [
+ "jobserver",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "cmake"
+version = "0.1.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "fixedbitset"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "indexmap"
+version = "1.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "jobserver"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.135"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
+
[[package]]
name = "librashader"
version = "0.1.0"
@@ -30,6 +133,27 @@ dependencies = [
"thiserror",
]
+[[package]]
+name = "librashader-reflect"
+version = "0.1.0"
+dependencies = [
+ "librashader",
+ "librashader-preprocess",
+ "naga",
+ "shaderc",
+ "spirv_cross",
+ "thiserror",
+]
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "memchr"
version = "2.5.0"
@@ -42,6 +166,24 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+[[package]]
+name = "naga"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707"
+dependencies = [
+ "bit-set",
+ "bitflags",
+ "indexmap",
+ "log",
+ "num-traits",
+ "petgraph",
+ "pp-rs",
+ "rustc-hash",
+ "spirv",
+ "thiserror",
+]
+
[[package]]
name = "nom"
version = "7.1.1"
@@ -63,6 +205,40 @@ dependencies = [
"nom",
]
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
+
+[[package]]
+name = "petgraph"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143"
+dependencies = [
+ "fixedbitset",
+ "indexmap",
+]
+
+[[package]]
+name = "pp-rs"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee"
+dependencies = [
+ "unicode-xid",
+]
+
[[package]]
name = "proc-macro2"
version = "1.0.47"
@@ -81,6 +257,63 @@ dependencies = [
"proc-macro2",
]
+[[package]]
+name = "roxmltree"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b"
+dependencies = [
+ "xmlparser",
+]
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "shaderc"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80e6fe602a861622769530a23bc40bfba31adbf186d0c8412e83f5519c5d6bee"
+dependencies = [
+ "libc",
+ "shaderc-sys",
+]
+
+[[package]]
+name = "shaderc-sys"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3794498651f8173d0afbc0bb8aca45ced111098227e755dde4c0ef2888c8d0bf"
+dependencies = [
+ "cmake",
+ "libc",
+ "roxmltree",
+]
+
+[[package]]
+name = "spirv"
+version = "0.2.0+1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830"
+dependencies = [
+ "bitflags",
+ "num-traits",
+]
+
+[[package]]
+name = "spirv_cross"
+version = "0.23.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60647fadbf83c4a72f0d7ea67a7ca3a81835cf442b8deae5c134c3e0055b2e14"
+dependencies = [
+ "cc",
+ "js-sys",
+ "wasm-bindgen",
+]
+
[[package]]
name = "syn"
version = "1.0.102"
@@ -117,3 +350,69 @@ name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
+[[package]]
+name = "xmlparser"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd"
diff --git a/Cargo.toml b/Cargo.toml
index 06e2d55..4247eb0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,5 +2,6 @@
members = [
"librashader",
"librashader-presets",
- "librashader-preprocess"
+ "librashader-preprocess",
+ "librashader-reflect"
]
\ No newline at end of file
diff --git a/librashader-preprocess/src/include.rs b/librashader-preprocess/src/include.rs
index eb8e494..88a1d30 100644
--- a/librashader-preprocess/src/include.rs
+++ b/librashader-preprocess/src/include.rs
@@ -6,7 +6,7 @@ use std::str::Lines;
#[cfg(feature = "line_directives")]
const GL_GOOGLE_CPP_STYLE_LINE_DIRECTIVE: &'static str =
- "#extension GL_GOOGLE_CPP_STYLE_LINE_DIRECTIVE : require";
+ "#extension GL_GOOGLE_cpp_style_line_directive : require";
fn read_file(path: impl AsRef) -> Result {
let path = path.as_ref();
diff --git a/librashader-reflect/Cargo.toml b/librashader-reflect/Cargo.toml
new file mode 100644
index 0000000..bf05e3a
--- /dev/null
+++ b/librashader-reflect/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "librashader-reflect"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+naga = { version = "0.10.0", features = ["glsl-in", "spv-in"] }
+shaderc = { version = "0.8.0" }
+spirv_cross = { version = "0.23.1", features = [ "glsl", "hlsl" ] }
+librashader = { path = "../librashader" }
+thiserror = "1.0.37"
+
+[dev-dependencies]
+librashader-preprocess = { path = "../librashader-preprocess", default-features = false }
diff --git a/librashader-reflect/src/error.rs b/librashader-reflect/src/error.rs
new file mode 100644
index 0000000..5360c73
--- /dev/null
+++ b/librashader-reflect/src/error.rs
@@ -0,0 +1,27 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum ShaderCompileError {
+ #[error("shader")]
+ NagaCompileError(Vec),
+
+ #[error("shaderc")]
+ ShaderCCompileError(#[from] shaderc::Error),
+
+ #[error("shaderc init")]
+ ShaderCInitError,
+}
+
+#[derive(Error, Debug)]
+pub enum ShaderReflectError {
+ #[error("shader")]
+ NagaCompileError(#[from] naga::front::spv::Error),
+ #[error("spirv")]
+ SpirvCrossError(#[from] spirv_cross::ErrorCode),
+}
+
+impl From> for ShaderCompileError {
+ fn from(err: Vec) -> Self {
+ ShaderCompileError::NagaCompileError(err)
+ }
+}
diff --git a/librashader-reflect/src/front/mod.rs b/librashader-reflect/src/front/mod.rs
new file mode 100644
index 0000000..33bd746
--- /dev/null
+++ b/librashader-reflect/src/front/mod.rs
@@ -0,0 +1,2 @@
+pub mod naga;
+pub mod shaderc;
diff --git a/librashader-reflect/src/front/naga.rs b/librashader-reflect/src/front/naga.rs
new file mode 100644
index 0000000..065deed
--- /dev/null
+++ b/librashader-reflect/src/front/naga.rs
@@ -0,0 +1,50 @@
+use crate::error::ShaderCompileError;
+use librashader::ShaderSource;
+use naga::front::glsl::{Options, Parser};
+use naga::{Module, ShaderStage};
+
+#[derive(Debug)]
+pub struct NagaCompilation {
+ pub(crate) vertex: Module,
+ pub(crate) fragment: Module,
+}
+
+pub fn compile_spirv(source: &ShaderSource) -> Result {
+ let mut parser = Parser::default();
+ let vertex = parser.parse(&Options::from(ShaderStage::Vertex), &source.vertex)?;
+ let fragment = parser.parse(&Options::from(ShaderStage::Fragment), &source.fragment)?;
+ Ok(NagaCompilation { vertex, fragment })
+}
+
+#[cfg(test)]
+mod test {
+ use crate::front::naga::compile_spirv;
+ use naga::front::glsl::{Options, Parser};
+ use naga::ShaderStage;
+
+ #[test]
+ pub fn compile_naga_test() {
+ let result = librashader_preprocess::load_shader_source(
+ "../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang",
+ )
+ .unwrap();
+
+ let fragment_source = result.fragment;
+ let mut parser = Parser::default();
+ println!("{fragment_source}");
+ let fragment = parser
+ .parse(&Options::from(ShaderStage::Fragment), &fragment_source)
+ .unwrap();
+ }
+
+ #[test]
+ pub fn compile_shader() {
+ let result = librashader_preprocess::load_shader_source(
+ "../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang",
+ )
+ .unwrap();
+ eprintln!("{:#}", &result.fragment[2930..2945]);
+ let spirv = compile_spirv(&result).unwrap();
+ eprintln!("{:?}", spirv)
+ }
+}
diff --git a/librashader-reflect/src/front/shaderc.rs b/librashader-reflect/src/front/shaderc.rs
new file mode 100644
index 0000000..ed8e354
--- /dev/null
+++ b/librashader-reflect/src/front/shaderc.rs
@@ -0,0 +1,136 @@
+use crate::error::ShaderCompileError;
+use librashader::ShaderSource;
+use shaderc::{CompilationArtifact, CompileOptions, GlslProfile, Limit, ShaderKind};
+
+pub struct GlslangCompilation {
+ pub(crate) vertex: CompilationArtifact,
+ pub(crate) fragment: CompilationArtifact,
+}
+
+fn get_shaderc_options() -> Result, ShaderCompileError> {
+ let mut options = CompileOptions::new().ok_or(ShaderCompileError::ShaderCInitError)?;
+ options.set_include_callback(|_, _, _, _| {
+ Err("RetroArch shaders must already have includes be preprocessed".into())
+ });
+ options.set_limit(Limit::MaxLights, 32);
+ options.set_limit(Limit::MaxClipPlanes, 6);
+ options.set_limit(Limit::MaxTextureUnits, 32);
+ options.set_limit(Limit::MaxTextureCoords, 32);
+ options.set_limit(Limit::MaxVertexAttribs, 64);
+ options.set_limit(Limit::MaxVertexUniformComponents, 4096);
+ options.set_limit(Limit::MaxVaryingFloats, 64);
+ options.set_limit(Limit::MaxVertexTextureImageUnits, 32);
+ options.set_limit(Limit::MaxCombinedTextureImageUnits, 80);
+ options.set_limit(Limit::MaxTextureImageUnits, 32);
+ options.set_limit(Limit::MaxFragmentUniformComponents, 4096);
+ options.set_limit(Limit::MaxDrawBuffers, 32);
+ options.set_limit(Limit::MaxVertexUniformVectors, 128);
+ options.set_limit(Limit::MaxVaryingVectors, 8);
+ options.set_limit(Limit::MaxFragmentUniformVectors, 16);
+ options.set_limit(Limit::MaxVertexOutputVectors, 16);
+ options.set_limit(Limit::MaxFragmentInputVectors, 15);
+ options.set_limit(Limit::MinProgramTexelOffset, -8);
+ options.set_limit(Limit::MaxProgramTexelOffset, 7);
+ options.set_limit(Limit::MaxClipDistances, 8);
+ options.set_limit(Limit::MaxComputeWorkGroupCountX, 65535);
+ options.set_limit(Limit::MaxComputeWorkGroupCountY, 65535);
+ options.set_limit(Limit::MaxComputeWorkGroupCountZ, 65535);
+ options.set_limit(Limit::MaxComputeWorkGroupSizeX, 1024);
+ options.set_limit(Limit::MaxComputeWorkGroupSizeY, 1024);
+ options.set_limit(Limit::MaxComputeWorkGroupSizeZ, 64);
+ options.set_limit(Limit::MaxComputeUniformComponents, 1024);
+ options.set_limit(Limit::MaxComputeTextureImageUnits, 16);
+ options.set_limit(Limit::MaxComputeImageUniforms, 8);
+ options.set_limit(Limit::MaxComputeAtomicCounters, 8);
+ options.set_limit(Limit::MaxComputeAtomicCounterBuffers, 1);
+ options.set_limit(Limit::MaxVaryingComponents, 60);
+ options.set_limit(Limit::MaxVertexOutputComponents, 64);
+ options.set_limit(Limit::MaxGeometryInputComponents, 64);
+ options.set_limit(Limit::MaxGeometryOutputComponents, 128);
+ options.set_limit(Limit::MaxFragmentInputComponents, 128);
+ options.set_limit(Limit::MaxImageUnits, 8);
+ options.set_limit(Limit::MaxCombinedImageUnitsAndFragmentOutputs, 8);
+ options.set_limit(Limit::MaxCombinedShaderOutputResources, 8);
+ options.set_limit(Limit::MaxImageSamples, 0);
+ options.set_limit(Limit::MaxVertexImageUniforms, 0);
+ options.set_limit(Limit::MaxTessControlImageUniforms, 0);
+ options.set_limit(Limit::MaxTessEvaluationImageUniforms, 0);
+ options.set_limit(Limit::MaxGeometryImageUniforms, 0);
+ options.set_limit(Limit::MaxFragmentImageUniforms, 8);
+ options.set_limit(Limit::MaxCombinedImageUniforms, 8);
+ options.set_limit(Limit::MaxGeometryTextureImageUnits, 16);
+ options.set_limit(Limit::MaxGeometryOutputVertices, 256);
+ options.set_limit(Limit::MaxGeometryTotalOutputComponents, 1024);
+ options.set_limit(Limit::MaxGeometryUniformComponents, 1024);
+ options.set_limit(Limit::MaxGeometryVaryingComponents, 64);
+ options.set_limit(Limit::MaxTessControlInputComponents, 128);
+ options.set_limit(Limit::MaxTessControlOutputComponents, 128);
+ options.set_limit(Limit::MaxTessControlTextureImageUnits, 16);
+ options.set_limit(Limit::MaxTessControlUniformComponents, 1024);
+ options.set_limit(Limit::MaxTessControlTotalOutputComponents, 4096);
+ options.set_limit(Limit::MaxTessEvaluationInputComponents, 128);
+ options.set_limit(Limit::MaxTessEvaluationOutputComponents, 128);
+ options.set_limit(Limit::MaxTessEvaluationTextureImageUnits, 16);
+ options.set_limit(Limit::MaxTessEvaluationUniformComponents, 1024);
+ options.set_limit(Limit::MaxTessPatchComponents, 120);
+ options.set_limit(Limit::MaxPatchVertices, 32);
+ options.set_limit(Limit::MaxTessGenLevel, 64);
+ options.set_limit(Limit::MaxViewports, 16);
+ options.set_limit(Limit::MaxVertexAtomicCounters, 0);
+ options.set_limit(Limit::MaxTessControlAtomicCounters, 0);
+ options.set_limit(Limit::MaxTessEvaluationAtomicCounters, 0);
+ options.set_limit(Limit::MaxGeometryAtomicCounters, 0);
+ options.set_limit(Limit::MaxFragmentAtomicCounters, 8);
+ options.set_limit(Limit::MaxCombinedAtomicCounters, 8);
+ options.set_limit(Limit::MaxAtomicCounterBindings, 1);
+ options.set_limit(Limit::MaxVertexAtomicCounterBuffers, 0);
+ options.set_limit(Limit::MaxTessControlAtomicCounterBuffers, 0);
+ options.set_limit(Limit::MaxTessEvaluationAtomicCounterBuffers, 0);
+ options.set_limit(Limit::MaxGeometryAtomicCounterBuffers, 0);
+ options.set_limit(Limit::MaxFragmentAtomicCounterBuffers, 1);
+ options.set_limit(Limit::MaxCombinedAtomicCounterBuffers, 1);
+ options.set_limit(Limit::MaxAtomicCounterBufferSize, 16384);
+ options.set_limit(Limit::MaxTransformFeedbackBuffers, 4);
+ options.set_limit(Limit::MaxTransformFeedbackInterleavedComponents, 64);
+ options.set_limit(Limit::MaxCullDistances, 8);
+ options.set_limit(Limit::MaxCombinedClipAndCullDistances, 8);
+ options.set_limit(Limit::MaxSamples, 4);
+
+ Ok(options)
+}
+
+pub fn compile_spirv(source: &ShaderSource) -> Result {
+ let compiler = shaderc::Compiler::new().ok_or(ShaderCompileError::ShaderCInitError)?;
+ let name = source.name.as_deref().unwrap_or("shader.glsl");
+ let options = get_shaderc_options()?;
+
+ let vertex = compiler.compile_into_spirv(
+ &source.vertex,
+ ShaderKind::Vertex,
+ name,
+ "main",
+ Some(&options),
+ )?;
+ let fragment = compiler.compile_into_spirv(
+ &source.fragment,
+ ShaderKind::Fragment,
+ name,
+ "main",
+ Some(&options),
+ )?;
+ Ok(GlslangCompilation { vertex, fragment })
+}
+
+#[cfg(test)]
+mod test {
+ use crate::front::shaderc::compile_spirv;
+
+ #[test]
+ pub fn compile_shader() {
+ let result = librashader_preprocess::load_shader_source(
+ "../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang",
+ )
+ .unwrap();
+ let spirv = compile_spirv(&result).unwrap();
+ }
+}
diff --git a/librashader-reflect/src/lib.rs b/librashader-reflect/src/lib.rs
new file mode 100644
index 0000000..e62a13a
--- /dev/null
+++ b/librashader-reflect/src/lib.rs
@@ -0,0 +1,3 @@
+mod error;
+mod front;
+mod reflect;
diff --git a/librashader-reflect/src/reflect/mod.rs b/librashader-reflect/src/reflect/mod.rs
new file mode 100644
index 0000000..d6cfd91
--- /dev/null
+++ b/librashader-reflect/src/reflect/mod.rs
@@ -0,0 +1,2 @@
+mod naga;
+mod spirv_cross;
diff --git a/librashader-reflect/src/reflect/naga.rs b/librashader-reflect/src/reflect/naga.rs
new file mode 100644
index 0000000..c891228
--- /dev/null
+++ b/librashader-reflect/src/reflect/naga.rs
@@ -0,0 +1,50 @@
+use crate::error::ShaderReflectError;
+use crate::front::naga::NagaCompilation;
+use crate::front::shaderc::GlslangCompilation;
+use naga::front::spv::Options;
+use naga::Module;
+
+#[derive(Debug)]
+pub struct NagaReflect {
+ vertex: Module,
+ fragment: Module,
+}
+
+impl TryFrom for NagaReflect {
+ type Error = ShaderReflectError;
+
+ fn try_from(value: NagaCompilation) -> Result {
+ Ok(NagaReflect {
+ vertex: value.vertex,
+ fragment: value.fragment,
+ })
+ }
+}
+
+impl TryFrom for NagaReflect {
+ type Error = ShaderReflectError;
+
+ fn try_from(value: GlslangCompilation) -> Result {
+ let ops = Options::default();
+ let vertex = naga::front::spv::parse_u8_slice(value.vertex.as_binary_u8(), &ops)?;
+ let fragment = naga::front::spv::parse_u8_slice(value.fragment.as_binary_u8(), &ops)?;
+ Ok(NagaReflect { vertex, fragment })
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use crate::reflect::naga::NagaReflect;
+ use naga::front::spv::Options;
+
+ #[test]
+ pub fn test_into() {
+ let result = librashader_preprocess::load_shader_source(
+ "../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang",
+ )
+ .unwrap();
+ let spirv = crate::front::shaderc::compile_spirv(&result).unwrap();
+
+ println!("{:?}", NagaReflect::try_from(spirv))
+ }
+}
diff --git a/librashader-reflect/src/reflect/spirv_cross.rs b/librashader-reflect/src/reflect/spirv_cross.rs
new file mode 100644
index 0000000..405ef77
--- /dev/null
+++ b/librashader-reflect/src/reflect/spirv_cross.rs
@@ -0,0 +1,46 @@
+use crate::error::ShaderReflectError;
+use crate::front::shaderc::GlslangCompilation;
+use spirv_cross::spirv::{Ast, Module};
+use std::fmt::Debug;
+
+pub struct SpirvCrossReflect
+where
+ T: spirv_cross::spirv::Target,
+{
+ vertex: Ast,
+ fragment: Ast,
+}
+
+impl TryFrom for SpirvCrossReflect
+where
+ T: spirv_cross::spirv::Target,
+ Ast: spirv_cross::spirv::Compile,
+ Ast: spirv_cross::spirv::Parse,
+{
+ type Error = ShaderReflectError;
+
+ fn try_from(value: GlslangCompilation) -> Result {
+ let vertex_module = Module::from_words(value.vertex.as_binary());
+ let fragment_module = Module::from_words(value.fragment.as_binary());
+
+ let vertex = Ast::parse(&vertex_module)?;
+ let fragment = Ast::parse(&fragment_module)?;
+ Ok(SpirvCrossReflect { vertex, fragment })
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use crate::reflect::spirv_cross::SpirvCrossReflect;
+ use spirv_cross::glsl;
+
+ #[test]
+ pub fn test_into() {
+ let result = librashader_preprocess::load_shader_source(
+ "../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang",
+ )
+ .unwrap();
+ let spirv = crate::front::shaderc::compile_spirv(&result).unwrap();
+ SpirvCrossReflect::::try_from(spirv).unwrap();
+ }
+}