#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Sizes {
None,
Probes,
PoolAndProbes,
}
pub struct SlangProgram {
pub file: &'static str,
pub entry: &'static str,
pub label: &'static str,
pub gates: &'static [&'static str],
pub sizes: Sizes,
pub msaa: bool,
}
pub static MAIN_BINDLESS_VERT: SlangProgram = SlangProgram {
file: "main_bindless.slang",
entry: "vertex_main_bindless",
label: "vert_bindless.slang",
gates: &[],
sizes: Sizes::PoolAndProbes,
msaa: false,
};
pub static MAIN_BINDLESS_FRAG: SlangProgram = SlangProgram {
file: "main_bindless.slang",
entry: "fragment_main_bindless",
label: "frag_bindless.slang",
gates: &[],
sizes: Sizes::PoolAndProbes,
msaa: false,
};
pub static CULL: SlangProgram = SlangProgram {
file: "cull.slang",
entry: "cull_kernel",
label: "cull.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static CULL_PHASE2: SlangProgram = SlangProgram {
file: "cull.slang",
entry: "cull_kernel",
label: "cull_phase2.slang",
gates: &["CULL_PHASE2"],
sizes: Sizes::None,
msaa: false,
};
pub static CULL_SHADOW: SlangProgram = SlangProgram {
file: "cull.slang",
entry: "cull_kernel",
label: "cull_shadow.slang",
gates: &["SHADOW_CULL"],
sizes: Sizes::None,
msaa: false,
};
pub static LIGHT_CULL: SlangProgram = SlangProgram {
file: "light_cull.slang",
entry: "light_cull_kernel",
label: "light_cull.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static HIZ_INIT_MSAA: SlangProgram = SlangProgram {
file: "hiz_build.slang",
entry: "hiz_init_msaa",
label: "hiz_init_msaa.slang",
gates: &["HIZ_INIT_MSAA"],
sizes: Sizes::None,
msaa: false,
};
pub static HIZ_INIT_SINGLE: SlangProgram = SlangProgram {
file: "hiz_build.slang",
entry: "hiz_init_single",
label: "hiz_init_single.slang",
gates: &["HIZ_INIT_SINGLE"],
sizes: Sizes::None,
msaa: false,
};
pub static HIZ_DOWNSAMPLE: SlangProgram = SlangProgram {
file: "hiz_build.slang",
entry: "hiz_downsample",
label: "hiz_downsample.slang",
gates: &["HIZ_DOWNSAMPLE"],
sizes: Sizes::None,
msaa: false,
};
pub static PROBE_MIP0: SlangProgram = SlangProgram {
file: "probe_prefilter.slang",
entry: "probe_mip0",
label: "probe_mip0.slang",
gates: &["PROBE_MIP0"],
sizes: Sizes::None,
msaa: false,
};
pub static PROBE_DOWNSAMPLE: SlangProgram = SlangProgram {
file: "probe_prefilter.slang",
entry: "probe_downsample",
label: "probe_downsample.slang",
gates: &["PROBE_DOWNSAMPLE"],
sizes: Sizes::None,
msaa: false,
};
pub static PROBE_GGX: SlangProgram = SlangProgram {
file: "probe_prefilter.slang",
entry: "probe_ggx",
label: "probe_ggx.slang",
gates: &["PROBE_GGX"],
sizes: Sizes::None,
msaa: false,
};
pub static GBUFFER_BINDLESS_VERT: SlangProgram = SlangProgram {
file: "gbuffer_prepass.slang",
entry: "gbuffer_prepass_vertex_bindless",
label: "gbuffer_prepass_vert_bindless.slang",
gates: &["GB_BINDLESS"],
sizes: Sizes::None,
msaa: false,
};
pub static GBUFFER_BINDLESS_FRAG: SlangProgram = SlangProgram {
file: "gbuffer_prepass.slang",
entry: "gbuffer_prepass_fragment_bindless",
label: "gbuffer_prepass_frag_bindless.slang",
gates: &["GB_FRAGMENT_BINDLESS"],
sizes: Sizes::None,
msaa: false,
};
pub static SHADOW_VERT: SlangProgram = SlangProgram {
file: "shadow.slang",
entry: "shadow_vertex_main",
label: "shadow_vert.slang",
gates: &["SHADOW_STATIC"],
sizes: Sizes::None,
msaa: false,
};
pub static SKINNED_SHADOW_VERT: SlangProgram = SlangProgram {
file: "shadow.slang",
entry: "shadow_vertex_main_skinned",
label: "shadow_vert_skinned.slang",
gates: &["SHADOW_SKINNED"],
sizes: Sizes::None,
msaa: false,
};
pub static SHADOW_BINDLESS_VERT: SlangProgram = SlangProgram {
file: "shadow.slang",
entry: "shadow_vertex_bindless",
label: "shadow_vert_bindless.slang",
gates: &["SHADOW_BINDLESS"],
sizes: Sizes::None,
msaa: false,
};
pub static FULLSCREEN_VERT: SlangProgram = SlangProgram {
file: "fullscreen.slang",
entry: "fullscreen_vertex",
label: "fullscreen_vert.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static TAA_FRAG: SlangProgram = SlangProgram {
file: "taa.slang",
entry: "taa_fragment_main",
label: "taa_frag.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static BLOOM_PREFILTER: SlangProgram = SlangProgram {
file: "bloom.slang",
entry: "bloom_prefilter_fragment",
label: "bloom_prefilter.slang",
gates: &["BLOOM_PREFILTER"],
sizes: Sizes::None,
msaa: false,
};
pub static BLOOM_DOWNSAMPLE: SlangProgram = SlangProgram {
file: "bloom.slang",
entry: "bloom_downsample_fragment",
label: "bloom_downsample.slang",
gates: &["BLOOM_DOWNSAMPLE"],
sizes: Sizes::None,
msaa: false,
};
pub static BLOOM_UPSAMPLE: SlangProgram = SlangProgram {
file: "bloom.slang",
entry: "bloom_upsample_fragment",
label: "bloom_upsample.slang",
gates: &["BLOOM_UPSAMPLE"],
sizes: Sizes::None,
msaa: false,
};
pub static COMPOSITE_FRAG: SlangProgram = SlangProgram {
file: "composite.slang",
entry: "composite_fragment",
label: "composite_frag.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static SSAO_KERNEL: SlangProgram = SlangProgram {
file: "ssao.slang",
entry: "ssao_kernel_fragment",
label: "ssao_kernel.slang",
gates: &["SSAO_KERNEL"],
sizes: Sizes::None,
msaa: false,
};
pub static SSAO_BLUR: SlangProgram = SlangProgram {
file: "ssao.slang",
entry: "ssao_blur_fragment",
label: "ssao_blur.slang",
gates: &["SSAO_BLUR"],
sizes: Sizes::None,
msaa: false,
};
pub static SSR_RESOLVE: SlangProgram = SlangProgram {
file: "ssr.slang",
entry: "ssr_resolve_fragment",
label: "ssr_resolve.slang",
gates: &[],
sizes: Sizes::Probes,
msaa: false,
};
pub static SSGI_GATHER: SlangProgram = SlangProgram {
file: "ssgi.slang",
entry: "ssgi_gather_fragment",
label: "ssgi_gather.slang",
gates: &["SSGI_GATHER"],
sizes: Sizes::None,
msaa: false,
};
pub static SSGI_COMPOSITE: SlangProgram = SlangProgram {
file: "ssgi.slang",
entry: "ssgi_composite_fragment",
label: "ssgi_composite.slang",
gates: &["SSGI_COMPOSITE"],
sizes: Sizes::None,
msaa: false,
};
pub static REFLECTION_BLUR: SlangProgram = SlangProgram {
file: "reflection.slang",
entry: "reflection_blur_fragment",
label: "reflection_blur.slang",
gates: &["REFLECTION_BLUR"],
sizes: Sizes::None,
msaa: false,
};
pub static REFLECTION_COMPOSITE: SlangProgram = SlangProgram {
file: "reflection.slang",
entry: "reflection_composite_fragment",
label: "reflection_composite.slang",
gates: &["REFLECTION_COMPOSITE"],
sizes: Sizes::None,
msaa: false,
};
pub static FOG_FROXEL: SlangProgram = SlangProgram {
file: "fog.slang",
entry: "fog_froxel_kernel",
label: "fog_froxel.slang",
gates: &["FOG_FROXEL"],
sizes: Sizes::None,
msaa: false,
};
pub static FOG_FRAG: SlangProgram = SlangProgram {
file: "fog.slang",
entry: "fog_fragment",
label: "fog_frag.slang",
gates: &[],
sizes: Sizes::None,
msaa: true,
};
pub static AUTO_EXPOSURE_BUILD: SlangProgram = SlangProgram {
file: "auto_exposure.slang",
entry: "histogram_build",
label: "auto_exposure_build.slang",
gates: &["AE_BUILD"],
sizes: Sizes::None,
msaa: false,
};
pub static AUTO_EXPOSURE_AVERAGE: SlangProgram = SlangProgram {
file: "auto_exposure.slang",
entry: "histogram_average",
label: "auto_exposure_average.slang",
gates: &["AE_AVERAGE"],
sizes: Sizes::None,
msaa: false,
};
pub static RT_SKIN: SlangProgram = SlangProgram {
file: "rt_skin.slang",
entry: "rt_skin",
label: "rt_skin.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static PARTICLE_SIMULATE: SlangProgram = SlangProgram {
file: "particle_simulate.slang",
entry: "particle_simulate",
label: "particle_simulate.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static PARTICLE_VERT: SlangProgram = SlangProgram {
file: "particle.slang",
entry: "particle_vertex",
label: "particle_vert.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static PARTICLE_FRAG: SlangProgram = SlangProgram {
file: "particle.slang",
entry: "particle_fragment",
label: "particle_frag.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static DECAL_VERT: SlangProgram = SlangProgram {
file: "decal.slang",
entry: "decal_vertex",
label: "decal_vert.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static DECAL_FRAG: SlangProgram = SlangProgram {
file: "decal.slang",
entry: "decal_fragment",
label: "decal_frag.slang",
gates: &[],
sizes: Sizes::None,
msaa: true,
};
pub static LINE_VERT: SlangProgram = SlangProgram {
file: "line.slang",
entry: "line_vertex",
label: "line_vert.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static LINE_FRAG: SlangProgram = SlangProgram {
file: "line.slang",
entry: "line_fragment",
label: "line_frag.slang",
gates: &[],
sizes: Sizes::None,
msaa: true,
};
pub static TEXT_VERT: SlangProgram = SlangProgram {
file: "text.slang",
entry: "text_vertex_main",
label: "text_vert.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static TEXT_FRAG: SlangProgram = SlangProgram {
file: "text.slang",
entry: "text_fragment_main",
label: "text_frag.slang",
gates: &[],
sizes: Sizes::None,
msaa: false,
};
pub static RT_REFLECTIONS_FRAG: SlangProgram = SlangProgram {
file: "rt_reflections.slang",
entry: "rt_reflections_fragment",
label: "rt_reflections.slang",
gates: &[],
sizes: Sizes::Probes,
msaa: false,
};
pub static RT_REFLECTIONS_FRAG_TEXTURED: SlangProgram = SlangProgram {
file: "rt_reflections.slang",
entry: "rt_reflections_fragment",
label: "rt_reflections_textured.slang",
gates: &["RT_TEXTURED"],
sizes: Sizes::PoolAndProbes,
msaa: false,
};
pub static GLASS_VERT: SlangProgram = SlangProgram {
file: "glass.slang",
entry: "glass_vertex",
label: "glass_vert.slang",
gates: &[],
sizes: Sizes::Probes,
msaa: true,
};
pub static GLASS_FRAG: SlangProgram = SlangProgram {
file: "glass.slang",
entry: "glass_fragment",
label: "glass_frag.slang",
gates: &[],
sizes: Sizes::Probes,
msaa: true,
};
pub static GLASS_FRAG_RT: SlangProgram = SlangProgram {
file: "glass.slang",
entry: "glass_rt_fragment",
label: "glass_frag_rt.slang",
gates: &["GLASS_RT"],
sizes: Sizes::Probes,
msaa: true,
};
pub static GLASS_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
file: "glass.slang",
entry: "glass_rt_fragment",
label: "glass_frag_rt_textured.slang",
gates: &["GLASS_RT", "RT_TEXTURED"],
sizes: Sizes::PoolAndProbes,
msaa: true,
};
pub static GLASS_MESH_VERT: SlangProgram = SlangProgram {
file: "glass_mesh.slang",
entry: "glass_mesh_vertex",
label: "glass_mesh_vert.slang",
gates: &[],
sizes: Sizes::Probes,
msaa: true,
};
pub static GLASS_MESH_FRAG_RT: SlangProgram = SlangProgram {
file: "glass_mesh.slang",
entry: "glass_mesh_rt_fragment",
label: "glass_mesh_frag_rt.slang",
gates: &[],
sizes: Sizes::Probes,
msaa: true,
};
pub static GLASS_MESH_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
file: "glass_mesh.slang",
entry: "glass_mesh_rt_fragment",
label: "glass_mesh_frag_rt_textured.slang",
gates: &["RT_TEXTURED"],
sizes: Sizes::PoolAndProbes,
msaa: true,
};
pub static WATER_VERT: SlangProgram = SlangProgram {
file: "water.slang",
entry: "water_vertex",
label: "water_vert.slang",
gates: &[],
sizes: Sizes::Probes,
msaa: true,
};
pub static WATER_FRAG: SlangProgram = SlangProgram {
file: "water.slang",
entry: "water_fragment",
label: "water_frag.slang",
gates: &[],
sizes: Sizes::Probes,
msaa: true,
};
pub static WATER_FRAG_RT: SlangProgram = SlangProgram {
file: "water.slang",
entry: "water_rt_fragment",
label: "water_frag_rt.slang",
gates: &["WATER_RT"],
sizes: Sizes::Probes,
msaa: true,
};
pub static WATER_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
file: "water.slang",
entry: "water_rt_fragment",
label: "water_frag_rt_textured.slang",
gates: &["WATER_RT", "RT_TEXTURED"],
sizes: Sizes::PoolAndProbes,
msaa: true,
};
pub static ALL: &[&SlangProgram] = &[
&MAIN_BINDLESS_VERT,
&MAIN_BINDLESS_FRAG,
&LIGHT_CULL,
&CULL,
&CULL_PHASE2,
&CULL_SHADOW,
&RT_SKIN,
&HIZ_INIT_MSAA,
&HIZ_INIT_SINGLE,
&HIZ_DOWNSAMPLE,
&PROBE_MIP0,
&PROBE_DOWNSAMPLE,
&PROBE_GGX,
&GBUFFER_BINDLESS_VERT,
&GBUFFER_BINDLESS_FRAG,
&SHADOW_VERT,
&SKINNED_SHADOW_VERT,
&SHADOW_BINDLESS_VERT,
&FULLSCREEN_VERT,
&TAA_FRAG,
&BLOOM_PREFILTER,
&BLOOM_DOWNSAMPLE,
&BLOOM_UPSAMPLE,
&COMPOSITE_FRAG,
&SSAO_KERNEL,
&SSAO_BLUR,
&SSR_RESOLVE,
&SSGI_GATHER,
&SSGI_COMPOSITE,
&REFLECTION_BLUR,
&REFLECTION_COMPOSITE,
&FOG_FROXEL,
&FOG_FRAG,
&AUTO_EXPOSURE_BUILD,
&AUTO_EXPOSURE_AVERAGE,
&PARTICLE_SIMULATE,
&PARTICLE_VERT,
&PARTICLE_FRAG,
&DECAL_VERT,
&DECAL_FRAG,
&LINE_VERT,
&LINE_FRAG,
&TEXT_VERT,
&TEXT_FRAG,
&RT_REFLECTIONS_FRAG,
&RT_REFLECTIONS_FRAG_TEXTURED,
&GLASS_VERT,
&GLASS_FRAG,
&GLASS_FRAG_RT,
&GLASS_FRAG_RT_TEXTURED,
&GLASS_MESH_VERT,
&GLASS_MESH_FRAG_RT,
&GLASS_MESH_FRAG_RT_TEXTURED,
&WATER_VERT,
&WATER_FRAG,
&WATER_FRAG_RT,
&WATER_FRAG_RT_TEXTURED,
];
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec::Vec;
#[test]
fn every_program_has_a_distinct_label() {
let mut labels: Vec<&str> = ALL.iter().map(|p| p.label).collect();
let declared = labels.len();
labels.sort_unstable();
labels.dedup();
assert_eq!(
labels.len(),
declared,
"two programs share a label, so they would share a precompiled artifact"
);
}
#[test]
fn every_program_names_an_embedded_shader() {
for p in ALL {
assert!(
crate::render::shaders::embedded(p.file).is_some(),
"{}: no embedded {}",
p.label,
p.file
);
}
}
#[test]
fn the_only_per_host_variant_is_the_sample_count() {
let sampled = ALL.iter().filter(|p| p.msaa).count();
assert!(sampled > 0, "the MSAA dimension went missing");
assert!(sampled < ALL.len(), "every program cannot read the depth");
for p in ALL {
assert!(!p.entry.is_empty(), "{}", p.label);
}
}
}