pub const VERTEX_COLOR_2D: &str = include_str!("../shaders/vertex_color_2d.slang");
pub const TRIANGLE: &str = include_str!("../shaders/triangle.slang");
pub const DIGITAL_CLOCK: &str = include_str!("../shaders/digital_clock.slang");
pub const PLASMA: &str = include_str!("../shaders/plasma.slang");
pub const GRADIENT: &str = include_str!("../shaders/gradient.slang");
pub const MANDELBROT: &str = include_str!("../shaders/mandelbrot.slang");
pub const TUNNEL: &str = include_str!("../shaders/tunnel.slang");
pub const METABALLS: &str = include_str!("../shaders/metaballs.slang");
pub const CHECKERBOARD: &str = include_str!("../shaders/checkerboard.slang");
pub const STARFIELD: &str = include_str!("../shaders/starfield.slang");
pub const PARTICLES: &str = include_str!("../shaders/particles.slang");
pub const SPINNING_CUBE: &str = include_str!("../shaders/spinning_cube.slang");
pub const DEPTH_TEST: &str = include_str!("../shaders/depth_test.slang");
#[cfg(test)]
mod tests {
use super::*;
use crate::types::OptimizationLevel;
#[test]
fn test_all_shaders_non_empty() {
assert!(!VERTEX_COLOR_2D.is_empty(), "VERTEX_COLOR_2D shader is empty");
assert!(!TRIANGLE.is_empty(), "TRIANGLE shader is empty");
assert!(!DIGITAL_CLOCK.is_empty(), "DIGITAL_CLOCK shader is empty");
assert!(!PLASMA.is_empty(), "PLASMA shader is empty");
assert!(!GRADIENT.is_empty(), "GRADIENT shader is empty");
assert!(!MANDELBROT.is_empty(), "MANDELBROT shader is empty");
assert!(!TUNNEL.is_empty(), "TUNNEL shader is empty");
assert!(!METABALLS.is_empty(), "METABALLS shader is empty");
assert!(!CHECKERBOARD.is_empty(), "CHECKERBOARD shader is empty");
assert!(!STARFIELD.is_empty(), "STARFIELD shader is empty");
assert!(!PARTICLES.is_empty(), "PARTICLES shader is empty");
assert!(!SPINNING_CUBE.is_empty(), "SPINNING_CUBE shader is empty");
}
#[test]
fn test_shaders_have_entry_points() {
let shaders = [
("VERTEX_COLOR_2D", VERTEX_COLOR_2D),
("TRIANGLE", TRIANGLE),
("DIGITAL_CLOCK", DIGITAL_CLOCK),
("PLASMA", PLASMA),
("GRADIENT", GRADIENT),
("MANDELBROT", MANDELBROT),
("TUNNEL", TUNNEL),
("METABALLS", METABALLS),
("CHECKERBOARD", CHECKERBOARD),
("STARFIELD", STARFIELD),
("PARTICLES", PARTICLES),
("SPINNING_CUBE", SPINNING_CUBE),
];
for (name, source) in shaders {
assert!(
source.contains("[goldy_vertex]"),
"{} missing vertex shader entry point",
name
);
assert!(
source.contains("[goldy_fragment]"),
"{} missing fragment shader entry point",
name
);
}
}
#[test]
fn test_shaders_have_main_functions() {
let shaders = [
("VERTEX_COLOR_2D", VERTEX_COLOR_2D),
("TRIANGLE", TRIANGLE),
("PLASMA", PLASMA),
];
for (name, source) in shaders {
assert!(source.contains("vs_main"), "{} missing vs_main function", name);
assert!(source.contains("fs_main"), "{} missing fs_main function", name);
}
}
#[test]
fn test_plasma_structure() {
assert!(
PLASMA.contains("goldy_compute") || PLASMA.contains("goldy_fragment"),
"PLASMA should use a goldy_* entry point"
);
assert!(
PLASMA.contains("import goldy_exp"),
"PLASMA should import goldy_exp module"
);
}
#[test]
fn test_plasma_compiles() {
use crate::slang::{ShaderTarget, SlangCompiler};
let compiler = SlangCompiler::new().expect("Failed to create Slang compiler");
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let shader_path = manifest_dir.join("shaders");
let shader_path_str = shader_path.to_string_lossy();
let result = compiler.compile_bindless_with_reflection_and_defines(
PLASMA,
ShaderTarget::Spirv,
&[],
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(result.is_ok(), "PLASMA failed to compile for SPIRV: {:?}", result.err());
#[cfg(windows)]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
PLASMA,
ShaderTarget::Dxil,
&[],
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(result.is_ok(), "PLASMA failed to compile for DXIL: {:?}", result.err());
}
#[cfg(target_os = "macos")]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
PLASMA,
ShaderTarget::Metal,
&[],
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(result.is_ok(), "PLASMA failed to compile for Metal: {:?}", result.err());
}
}
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_descriptor_handle_compiles() {
use crate::slang::{ShaderTarget, SlangCompiler};
let compiler = SlangCompiler::new().expect("Failed to create Slang compiler");
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let shader_path = manifest_dir.join("shaders");
let shader_path_str = shader_path.to_string_lossy();
let test_shader = std::fs::read_to_string(shader_path.join("test_descriptor_handle.slang"))
.expect("Failed to read test_descriptor_handle.slang");
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Spirv,
&[],
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_descriptor_handle failed to compile for SPIRV: {:?}",
result.err()
);
#[cfg(windows)]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Dxil,
&[],
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_descriptor_handle failed to compile for DXIL: {:?}",
result.err()
);
}
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Metal,
&[],
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_descriptor_handle failed to compile for Metal: {:?}",
result.err()
);
}
#[test]
fn test_access_functions_compiles() {
use crate::slang::{ShaderTarget, SlangCompiler};
let compiler = SlangCompiler::new().expect("Failed to create Slang compiler");
let test_shader = include_str!("../shaders/test_access_functions.slang");
let shader_path = std::env::current_dir()
.unwrap()
.join("shaders")
.to_string_lossy()
.to_string();
let shader_path_str = shader_path.as_str();
let result = compiler.compile_bindless_with_reflection_and_defines(
test_shader,
ShaderTarget::Spirv,
&[],
&[shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_access_functions failed to compile for SPIRV: {:?}",
result.err()
);
#[cfg(windows)]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
test_shader,
ShaderTarget::Dxil,
&[],
&[shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_access_functions failed to compile for DXIL: {:?}",
result.err()
);
}
let result = compiler.compile_bindless_with_reflection_and_defines(
test_shader,
ShaderTarget::Metal,
&[],
&[shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_access_functions failed to compile for Metal: {:?}",
result.err()
);
}
#[test]
fn test_goldy_exp_math_compiles() {
use crate::slang::{ShaderTarget, SlangCompiler, SlangStage};
let compiler = SlangCompiler::new().expect("Failed to create Slang compiler");
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let shader_path = manifest_dir.join("shaders");
let shader_path_str = shader_path.to_string_lossy();
let test_shader = std::fs::read_to_string(shader_path.join("test_goldy_exp_math.slang"))
.expect("Failed to read test_goldy_exp_math.slang");
let entry = &[("cs_main", SlangStage::Compute)];
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Spirv,
entry,
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_goldy_exp_math failed to compile for SPIRV: {:?}",
result.err()
);
#[cfg(windows)]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Dxil,
entry,
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_goldy_exp_math failed to compile for DXIL: {:?}",
result.err()
);
}
#[cfg(target_os = "macos")]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Metal,
entry,
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_goldy_exp_math failed to compile for Metal: {:?}",
result.err()
);
}
}
#[test]
fn test_algebra_compiles() {
use crate::slang::{ShaderTarget, SlangCompiler, SlangStage};
let compiler = SlangCompiler::new().expect("Failed to create Slang compiler");
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let shader_path = manifest_dir.join("shaders");
let shader_path_str = shader_path.to_string_lossy();
let test_shader =
std::fs::read_to_string(shader_path.join("test_algebra.slang")).expect("Failed to read test_algebra.slang");
let entry = &[("cs_main", SlangStage::Compute)];
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Spirv,
entry,
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_algebra failed to compile for SPIRV: {:?}",
result.err()
);
#[cfg(windows)]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Dxil,
entry,
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_algebra failed to compile for DXIL: {:?}",
result.err()
);
}
#[cfg(target_os = "macos")]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Metal,
entry,
&[&shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_algebra failed to compile for Metal: {:?}",
result.err()
);
}
}
#[test]
fn test_collectives_compiles() {
use crate::slang::{ShaderTarget, SlangCompiler, SlangStage};
let compiler = SlangCompiler::new().expect("Failed to create Slang compiler");
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let goldy_shaders = manifest_dir.join("shaders");
let goldy_path = goldy_shaders.to_string_lossy();
let test_shader = std::fs::read_to_string(goldy_shaders.join("test_collectives.slang"))
.expect("Failed to read test_collectives.slang");
let entry = &[("cs_main", SlangStage::Compute)];
let search_paths: &[&str] = &[&goldy_path];
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Spirv,
entry,
search_paths,
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_collectives failed to compile for SPIRV: {:?}",
result.err()
);
#[cfg(windows)]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Dxil,
entry,
search_paths,
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_collectives failed to compile for DXIL: {:?}",
result.err()
);
}
#[cfg(target_os = "macos")]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Metal,
entry,
search_paths,
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_collectives failed to compile for Metal: {:?}",
result.err()
);
}
}
#[test]
fn test_monoids_compiles() {
use crate::slang::{ShaderTarget, SlangCompiler, SlangStage};
let compiler = SlangCompiler::new().expect("Failed to create Slang compiler");
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let goldy_shaders = manifest_dir.join("shaders");
let goldy_path = goldy_shaders.to_string_lossy();
let test_shader = std::fs::read_to_string(goldy_shaders.join("test_monoids.slang"))
.expect("Failed to read test_monoids.slang");
let entry = &[("cs_main", SlangStage::Compute)];
let search_paths: &[&str] = &[&goldy_path];
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Spirv,
entry,
search_paths,
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_monoids failed to compile for SPIRV: {:?}",
result.err()
);
#[cfg(windows)]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Dxil,
entry,
search_paths,
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_monoids failed to compile for DXIL: {:?}",
result.err()
);
}
#[cfg(target_os = "macos")]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
&test_shader,
ShaderTarget::Metal,
entry,
search_paths,
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"test_monoids failed to compile for Metal: {:?}",
result.err()
);
}
}
#[test]
fn test_rain_snow_compiles() {
use crate::slang::{ShaderTarget, SlangCompiler, SlangStage};
let compiler = SlangCompiler::new().expect("Failed to create Slang compiler");
let test_shader = include_str!("../shaders/rain_snow_update.slang");
let shader_path = std::env::current_dir()
.unwrap()
.join("shaders")
.to_string_lossy()
.to_string();
let shader_path_str = shader_path.as_str();
let entry = &[("cs_main", SlangStage::Compute)];
let result = compiler.compile_bindless_with_reflection_and_defines(
test_shader,
ShaderTarget::Spirv,
entry,
&[shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"rain_snow_update failed to compile for SPIRV: {:?}",
result.err()
);
#[cfg(windows)]
{
let result = compiler.compile_bindless_with_reflection_and_defines(
test_shader,
ShaderTarget::Dxil,
entry,
&[shader_path_str],
&[],
&[],
OptimizationLevel::Default,
);
assert!(
result.is_ok(),
"rain_snow_update failed to compile for DXIL: {:?}",
result.err()
);
}
}
}