From 9741ab2cd12a541bcc162a40d7b42006f8421b58 Mon Sep 17 00:00:00 2001 From: chyyran Date: Wed, 21 Feb 2024 01:00:23 -0500 Subject: [PATCH] ci: add a full test suite for reflecting things --- .github/workflows/full-test.yml | 35 +++++ Cargo.lock | 3 + librashader-reflect/src/reflect/cross/mod.rs | 3 +- librashader/Cargo.toml | 5 + librashader/src/lib.rs | 2 +- librashader/tests/reflect.rs | 137 +++++++++++++++++++ 6 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/full-test.yml create mode 100644 librashader/tests/reflect.rs diff --git a/.github/workflows/full-test.yml b/.github/workflows/full-test.yml new file mode 100644 index 0000000..7147c66 --- /dev/null +++ b/.github/workflows/full-test.yml @@ -0,0 +1,35 @@ +name: integration test shader reflection + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] +env: + CARGO_TERM_COLOR: always + +jobs: + approve-full-test: + name: "approval" + runs-on: ubuntu-latest + steps: + - name: Approve + run: echo Full test suite needs approval by a maintainer + test: + environment: + name: full-test + runs-on: windows-latest + needs: [approve-full-test] + continue-on-error: false + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + - name: Install nightly Rust + uses: actions-rs/toolchain@v1.0.6 + with: + toolchain: nightly + override: true + - name: Test + run: cargo test -p librashader --test reflect -- --nocapture diff --git a/Cargo.lock b/Cargo.lock index c8a510e..dc7e79b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1462,6 +1462,7 @@ name = "librashader" version = "0.2.2" dependencies = [ "ash", + "glob", "halfbrown", "icrate 0.1.0", "librashader-cache", @@ -1477,6 +1478,8 @@ dependencies = [ "librashader-runtime-vk", "librashader-runtime-wgpu", "objc2 0.5.0", + "once_cell", + "rayon", "wgpu", "wgpu-types", "windows 0.48.0", diff --git a/librashader-reflect/src/reflect/cross/mod.rs b/librashader-reflect/src/reflect/cross/mod.rs index db2bf18..01353f7 100644 --- a/librashader-reflect/src/reflect/cross/mod.rs +++ b/librashader-reflect/src/reflect/cross/mod.rs @@ -741,6 +741,7 @@ mod test { use crate::front::{Glslang, ShaderInputCompiler}; use crate::reflect::semantics::{Semantic, ShaderSemantics, UniformSemantic, UniqueSemantics}; + use librashader_common::map::FastHashMap; use librashader_preprocess::ShaderSource; use spirv_cross::glsl; use spirv_cross::glsl::{CompilerOptions, Version}; @@ -748,7 +749,7 @@ mod test { #[test] pub fn test_into() { let result = ShaderSource::load("../test/basic.slang").unwrap(); - let mut uniform_semantics: FxHashMap = Default::default(); + let mut uniform_semantics: FastHashMap = Default::default(); for (_index, param) in result.parameters.iter().enumerate() { uniform_semantics.insert( diff --git a/librashader/Cargo.toml b/librashader/Cargo.toml index fc2e8a6..876250c 100644 --- a/librashader/Cargo.toml +++ b/librashader/Cargo.toml @@ -74,6 +74,11 @@ full = ["runtime-all", "reflect-all", "preprocess", "presets"] # cache hack docsrs = ["librashader-cache/docsrs", "objc2/unstable-docsrs"] +[dev-dependencies] +glob = "0.3.1" +rayon = "1.6.1" +once_cell = "1.19.0" + [package.metadata.docs.rs] targets = [ "x86_64-pc-windows-msvc", "x86_64-unknown-linux-gnu", diff --git a/librashader/src/lib.rs b/librashader/src/lib.rs index bbd229e..198c18c 100644 --- a/librashader/src/lib.rs +++ b/librashader/src/lib.rs @@ -141,9 +141,9 @@ pub mod reflect { pub use librashader_reflect::back::targets::DXIL; pub use librashader_reflect::back::targets::GLSL; pub use librashader_reflect::back::targets::HLSL; + pub use librashader_reflect::back::targets::MSL; pub use librashader_reflect::back::targets::SPIRV; pub use librashader_reflect::back::targets::WGSL; - pub use librashader_reflect::back::targets::MSL; } pub use librashader_reflect::error::*; diff --git a/librashader/tests/reflect.rs b/librashader/tests/reflect.rs new file mode 100644 index 0000000..27579b0 --- /dev/null +++ b/librashader/tests/reflect.rs @@ -0,0 +1,137 @@ +use glob::glob; +use librashader::preprocess::ShaderSource; +use librashader::presets::ShaderPreset; +use rayon::prelude::*; +use std::error::Error; +use std::path::PathBuf; +use std::sync::RwLock; + +use librashader::reflect::cross::SpirvCross; +use librashader::reflect::naga::Naga; +use librashader::reflect::targets::*; +use librashader::reflect::CompilePresetTarget; +use librashader::reflect::FromCompilation; +use librashader::reflect::OutputTarget; +use librashader::reflect::SpirvCompilation; + +use once_cell::sync::Lazy; +static ALL_SLANG_PRESETS: Lazy>> = + Lazy::new(|| RwLock::new(collect_all_loadable_slang_presets())); + +fn collect_all_slang_presets() -> Vec<(PathBuf, ShaderPreset)> { + let presets = glob("../test/shaders_slang/**/*.slangp") + .unwrap() + .collect::>() + .into_par_iter() + .filter_map(|entry| { + if let Ok(path) = entry { + if let Ok(preset) = ShaderPreset::try_parse(&path) { + println!("[INFO] Parsing preset {path:?}"); + return Some((path, preset)); + } + } + return None; + }) + .collect(); + + presets +} + +fn collect_all_loadable_slang_presets() -> Vec<(PathBuf, ShaderPreset)> { + let mut presets = collect_all_slang_presets(); + presets.retain(|(_, preset)| { + !preset + .shaders + .par_iter() + .any(|shader| ShaderSource::load(&shader.name).is_err()) + }); + + presets +} + +#[test] +pub fn preprocess_all_slang_presets_parsed() { + let presets = collect_all_slang_presets(); + + for (path, preset) in presets { + preset.shaders.into_par_iter().for_each(|shader| { + if let Err(e) = ShaderSource::load(&shader.name) { + eprintln!( + "[ERROR] Failed to preprocess shader {} from preset {}: {:?}", + shader.name.display(), + path.display(), + e + ); + } + }) + } +} + +fn compile_presets() +where + O: Sized, + O: FromCompilation, +{ + let presets = ALL_SLANG_PRESETS.read().unwrap(); + presets.par_iter().for_each(|(path, preset)| { + println!( + "[INFO] Compiling {path:?} into {} reflecting with {}", + std::any::type_name::(), + std::any::type_name::() + ); + if let Err(e) = O::compile_preset_passes::>( + preset.shaders.clone(), + &preset.textures, + ) { + eprintln!("[ERROR] {:?} ({path:?})", e); + } + }); +} + +#[test] +#[cfg(feature = "reflect-cross")] +pub fn compile_all_slang_presets_spirv_cross() { + compile_presets::(); +} + +#[test] +#[cfg(feature = "reflect-cross")] +pub fn compile_all_slang_presets_hlsl_cross() { + compile_presets::(); +} + +#[test] +#[cfg(feature = "reflect-cross")] +pub fn compile_all_slang_presets_glsl_cross() { + compile_presets::(); +} + +#[test] +#[cfg(feature = "reflect-cross")] +pub fn compile_all_slang_presets_msl_cross() { + compile_presets::(); +} + +#[test] +#[cfg(all(target_os = "windows", feature = "reflect-dxil"))] +pub fn compile_all_slang_presets_dxil_cross() { + compile_presets::(); +} + +#[test] +#[cfg(feature = "reflect-naga")] +pub fn compile_all_slang_presets_spirv_naga() { + compile_presets::(); +} + +#[test] +#[cfg(feature = "reflect-naga")] +pub fn compile_all_slang_presets_msl_naga() { + compile_presets::(); +} + +#[test] +#[cfg(feature = "reflect-naga")] +pub fn compile_all_slang_presets_wgsl_naga() { + compile_presets::(); +}