From 0f91b9a49e0a778a43484c18bb1bc54f03f5c205 Mon Sep 17 00:00:00 2001 From: chyyran Date: Sun, 23 Oct 2022 02:36:41 -0400 Subject: [PATCH] reflect: add reflection crate --- .idea/src.iml | 1 + Cargo.lock | 299 ++++++++++++++++++ Cargo.toml | 3 +- librashader-preprocess/src/include.rs | 2 +- librashader-reflect/Cargo.toml | 16 + librashader-reflect/src/error.rs | 27 ++ librashader-reflect/src/front/mod.rs | 2 + librashader-reflect/src/front/naga.rs | 50 +++ librashader-reflect/src/front/shaderc.rs | 136 ++++++++ librashader-reflect/src/lib.rs | 3 + librashader-reflect/src/reflect/mod.rs | 2 + librashader-reflect/src/reflect/naga.rs | 50 +++ .../src/reflect/spirv_cross.rs | 46 +++ 13 files changed, 635 insertions(+), 2 deletions(-) create mode 100644 librashader-reflect/Cargo.toml create mode 100644 librashader-reflect/src/error.rs create mode 100644 librashader-reflect/src/front/mod.rs create mode 100644 librashader-reflect/src/front/naga.rs create mode 100644 librashader-reflect/src/front/shaderc.rs create mode 100644 librashader-reflect/src/lib.rs create mode 100644 librashader-reflect/src/reflect/mod.rs create mode 100644 librashader-reflect/src/reflect/naga.rs create mode 100644 librashader-reflect/src/reflect/spirv_cross.rs 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(); + } +}