use concinnity_slang as slang;
pub(crate) struct SlangProgram {
pub file: &'static str,
pub embedded: &'static str,
pub entry: &'static str,
pub profile: &'static str,
pub label: &'static str,
pub defines: &'static [(&'static str, &'static str)],
}
const MAIN_BINDLESS_SLANG: &str = include_str!("../shaders/main_bindless.slang");
const LIGHT_CULL_SLANG: &str = include_str!("../shaders/light_cull.slang");
const HIZ_BUILD_SLANG: &str = include_str!("../shaders/hiz_build.slang");
const FOG_SLANG: &str = include_str!("../shaders/fog.slang");
const AUTO_EXPOSURE_SLANG: &str = include_str!("../shaders/auto_exposure.slang");
const PARTICLE_SIMULATE_SLANG: &str = include_str!("../shaders/particle_simulate.slang");
const RT_SKIN_SLANG: &str = include_str!("../shaders/rt_skin.slang");
const GBUFFER_PREPASS_SLANG: &str = include_str!("../shaders/gbuffer_prepass.slang");
const SHADOW_SLANG: &str = include_str!("../shaders/shadow.slang");
const FULLSCREEN_SLANG: &str = include_str!("../shaders/fullscreen.slang");
const TAA_SLANG: &str = include_str!("../shaders/taa.slang");
const BLOOM_SLANG: &str = include_str!("../shaders/bloom.slang");
const COMPOSITE_SLANG: &str = include_str!("../shaders/composite.slang");
const SSAO_SLANG: &str = include_str!("../shaders/ssao.slang");
const SSR_SLANG: &str = include_str!("../shaders/ssr.slang");
const SSGI_SLANG: &str = include_str!("../shaders/ssgi.slang");
const REFLECTION_SLANG: &str = include_str!("../shaders/reflection.slang");
const RT_REFLECTIONS_SLANG: &str = include_str!("../shaders/rt_reflections.slang");
const GLASS_SLANG: &str = include_str!("../shaders/glass.slang");
const WATER_SLANG: &str = include_str!("../shaders/water.slang");
const GLASS_MESH_SLANG: &str = include_str!("../shaders/glass_mesh.slang");
const PARTICLE_SLANG: &str = include_str!("../shaders/particle.slang");
const DECAL_SLANG: &str = include_str!("../shaders/decal.slang");
const LINE_SLANG: &str = include_str!("../shaders/line.slang");
const TEXT_SLANG: &str = include_str!("../shaders/text.slang");
const MAIN_DEFINES: &[(&str, &str)] = &[("DXIL_ABI", "1"), ("MAX_PROBES", "8")];
const SSR_DEFINES: &[(&str, &str)] = &[("MAX_PROBES", "8"), ("SPLIT_PROBE_SAMPLER", "1")];
pub(super) static MAIN_BINDLESS_VERT: SlangProgram = SlangProgram {
file: "main_bindless.slang",
embedded: MAIN_BINDLESS_SLANG,
entry: "vertex_main_bindless",
profile: "vs_6_0",
label: "vert_bindless.slang",
defines: MAIN_DEFINES,
};
pub(super) static MAIN_BINDLESS_FRAG: SlangProgram = SlangProgram {
file: "main_bindless.slang",
embedded: MAIN_BINDLESS_SLANG,
entry: "fragment_main_bindless",
profile: "ps_6_0",
label: "frag_bindless.slang",
defines: MAIN_DEFINES,
};
pub(super) static LIGHT_CULL: SlangProgram = SlangProgram {
file: "light_cull.slang",
embedded: LIGHT_CULL_SLANG,
entry: "light_cull_kernel",
profile: "cs_6_0",
label: "light_cull.slang",
defines: &[],
};
pub(super) static HIZ_INIT_SINGLE: SlangProgram = SlangProgram {
file: "hiz_build.slang",
embedded: HIZ_BUILD_SLANG,
entry: "hiz_init_single",
profile: "cs_6_0",
label: "hiz_init_single.slang",
defines: &[("HIZ_INIT_SINGLE", "1")],
};
pub(super) static HIZ_INIT_MSAA: SlangProgram = SlangProgram {
file: "hiz_build.slang",
embedded: HIZ_BUILD_SLANG,
entry: "hiz_init_msaa",
profile: "cs_6_0",
label: "hiz_init_msaa.slang",
defines: &[("HIZ_INIT_MSAA", "1")],
};
pub(super) static HIZ_DOWNSAMPLE: SlangProgram = SlangProgram {
file: "hiz_build.slang",
embedded: HIZ_BUILD_SLANG,
entry: "hiz_downsample",
profile: "cs_6_0",
label: "hiz_downsample.slang",
defines: &[("HIZ_DOWNSAMPLE", "1")],
};
const GB_STATIC: &[(&str, &str)] = &[("GB_STATIC", "1"), ("DXIL_ABI", "1")];
const GB_INSTANCED: &[(&str, &str)] = &[("GB_INSTANCED", "1"), ("DXIL_ABI", "1")];
const GB_SKINNED: &[(&str, &str)] = &[("GB_SKINNED", "1"), ("DXIL_ABI", "1")];
const GB_BINDLESS: &[(&str, &str)] = &[("GB_BINDLESS", "1"), ("DXIL_ABI", "1")];
const GB_FRAGMENT: &[(&str, &str)] = &[("GB_FRAGMENT", "1"), ("DXIL_ABI", "1")];
const GB_FRAGMENT_BINDLESS: &[(&str, &str)] = &[("GB_FRAGMENT_BINDLESS", "1"), ("DXIL_ABI", "1")];
const SHADOW_STATIC: &[(&str, &str)] = &[("SHADOW_STATIC", "1"), ("DXIL_ABI", "1")];
const SHADOW_SKINNED: &[(&str, &str)] = &[("SHADOW_SKINNED", "1"), ("DXIL_ABI", "1")];
const SHADOW_BINDLESS: &[(&str, &str)] = &[("SHADOW_BINDLESS", "1"), ("DXIL_ABI", "1")];
pub(super) static GBUFFER_PREPASS_VERT: SlangProgram = SlangProgram {
file: "gbuffer_prepass.slang",
embedded: GBUFFER_PREPASS_SLANG,
entry: "gbuffer_prepass_vertex",
profile: "vs_6_0",
label: "gbuffer_prepass_vert.slang",
defines: GB_STATIC,
};
pub(super) static GBUFFER_PREPASS_VERT_INSTANCED: SlangProgram = SlangProgram {
file: "gbuffer_prepass.slang",
embedded: GBUFFER_PREPASS_SLANG,
entry: "gbuffer_prepass_vertex_instanced",
profile: "vs_6_0",
label: "gbuffer_prepass_vert_instanced.slang",
defines: GB_INSTANCED,
};
pub(super) static GBUFFER_PREPASS_VERT_SKINNED: SlangProgram = SlangProgram {
file: "gbuffer_prepass.slang",
embedded: GBUFFER_PREPASS_SLANG,
entry: "gbuffer_prepass_vertex_skinned",
profile: "vs_6_0",
label: "gbuffer_prepass_vert_skinned.slang",
defines: GB_SKINNED,
};
pub(super) static GBUFFER_BINDLESS_VERT: SlangProgram = SlangProgram {
file: "gbuffer_prepass.slang",
embedded: GBUFFER_PREPASS_SLANG,
entry: "gbuffer_prepass_vertex_bindless",
profile: "vs_6_0",
label: "gbuffer_prepass_vert_bindless.slang",
defines: GB_BINDLESS,
};
pub(super) static GBUFFER_PREPASS_FRAG: SlangProgram = SlangProgram {
file: "gbuffer_prepass.slang",
embedded: GBUFFER_PREPASS_SLANG,
entry: "gbuffer_prepass_fragment",
profile: "ps_6_0",
label: "gbuffer_prepass_frag.slang",
defines: GB_FRAGMENT,
};
pub(super) static GBUFFER_BINDLESS_FRAG: SlangProgram = SlangProgram {
file: "gbuffer_prepass.slang",
embedded: GBUFFER_PREPASS_SLANG,
entry: "gbuffer_prepass_fragment_bindless",
profile: "ps_6_0",
label: "gbuffer_prepass_frag_bindless.slang",
defines: GB_FRAGMENT_BINDLESS,
};
pub(super) static SHADOW_VERT: SlangProgram = SlangProgram {
file: "shadow.slang",
embedded: SHADOW_SLANG,
entry: "shadow_vertex_main",
profile: "vs_6_0",
label: "shadow_vert.slang",
defines: SHADOW_STATIC,
};
pub(super) static SKINNED_SHADOW_VERT: SlangProgram = SlangProgram {
file: "shadow.slang",
embedded: SHADOW_SLANG,
entry: "shadow_vertex_main_skinned",
profile: "vs_6_0",
label: "shadow_vert_skinned.slang",
defines: SHADOW_SKINNED,
};
pub(super) static SHADOW_BINDLESS_VERT: SlangProgram = SlangProgram {
file: "shadow.slang",
embedded: SHADOW_SLANG,
entry: "shadow_vertex_bindless",
profile: "vs_6_0",
label: "shadow_vert_bindless.slang",
defines: SHADOW_BINDLESS,
};
const FOG_FROXEL_DEFINES: &[(&str, &str)] = &[("FOG_FROXEL", "1"), ("DXIL_SPLIT", "1")];
pub(super) static FOG_FROXEL: SlangProgram = SlangProgram {
file: "fog.slang",
embedded: FOG_SLANG,
entry: "fog_froxel_kernel",
profile: "cs_6_0",
label: "fog_froxel.slang",
defines: FOG_FROXEL_DEFINES,
};
pub(super) static FOG_FRAG: SlangProgram = SlangProgram {
file: "fog.slang",
embedded: FOG_SLANG,
entry: "fog_fragment",
profile: "ps_6_0",
label: "fog_frag.slang",
defines: &[("USE_MSAA", "0"), ("DXIL_STAGE_PACKING", "1")],
};
pub(super) static FOG_FRAG_MSAA: SlangProgram = SlangProgram {
file: "fog.slang",
embedded: FOG_SLANG,
entry: "fog_fragment",
profile: "ps_6_0",
label: "fog_frag_msaa.slang",
defines: &[("USE_MSAA", "1"), ("DXIL_STAGE_PACKING", "1")],
};
pub(super) static AUTO_EXPOSURE_BUILD: SlangProgram = SlangProgram {
file: "auto_exposure.slang",
embedded: AUTO_EXPOSURE_SLANG,
entry: "histogram_build",
profile: "cs_6_0",
label: "auto_exposure_build.slang",
defines: &[("AE_BUILD", "1")],
};
pub(super) static AUTO_EXPOSURE_AVERAGE: SlangProgram = SlangProgram {
file: "auto_exposure.slang",
embedded: AUTO_EXPOSURE_SLANG,
entry: "histogram_average",
profile: "cs_6_0",
label: "auto_exposure_average.slang",
defines: &[("AE_AVERAGE", "1")],
};
pub(super) static RT_SKIN: SlangProgram = SlangProgram {
file: "rt_skin.slang",
embedded: RT_SKIN_SLANG,
entry: "rt_skin",
profile: "cs_6_5",
label: "rt_skin.slang",
defines: &[],
};
pub(super) static PARTICLE_SIMULATE: SlangProgram = SlangProgram {
file: "particle_simulate.slang",
embedded: PARTICLE_SIMULATE_SLANG,
entry: "particle_simulate",
profile: "cs_6_0",
label: "particle_simulate.slang",
defines: &[],
};
pub(super) static FULLSCREEN_VERT: SlangProgram = SlangProgram {
file: "fullscreen.slang",
embedded: FULLSCREEN_SLANG,
entry: "fullscreen_vertex",
profile: "vs_6_0",
label: "fullscreen_vert.slang",
defines: &[],
};
pub(super) static TAA_FRAG: SlangProgram = SlangProgram {
file: "taa.slang",
embedded: TAA_SLANG,
entry: "taa_fragment_main",
profile: "ps_6_0",
label: "taa_frag.slang",
defines: &[],
};
pub(super) static BLOOM_PREFILTER: SlangProgram = SlangProgram {
file: "bloom.slang",
embedded: BLOOM_SLANG,
entry: "bloom_prefilter_fragment",
profile: "ps_6_0",
label: "bloom_prefilter.slang",
defines: &[("BLOOM_PREFILTER", "1")],
};
pub(super) static BLOOM_DOWNSAMPLE: SlangProgram = SlangProgram {
file: "bloom.slang",
embedded: BLOOM_SLANG,
entry: "bloom_downsample_fragment",
profile: "ps_6_0",
label: "bloom_downsample.slang",
defines: &[("BLOOM_DOWNSAMPLE", "1")],
};
pub(super) static BLOOM_UPSAMPLE: SlangProgram = SlangProgram {
file: "bloom.slang",
embedded: BLOOM_SLANG,
entry: "bloom_upsample_fragment",
profile: "ps_6_0",
label: "bloom_upsample.slang",
defines: &[("BLOOM_UPSAMPLE", "1")],
};
pub(super) static COMPOSITE_FRAG: SlangProgram = SlangProgram {
file: "composite.slang",
embedded: COMPOSITE_SLANG,
entry: "composite_fragment",
profile: "ps_6_0",
label: "composite_frag.slang",
defines: &[],
};
pub(super) static SSAO_KERNEL: SlangProgram = SlangProgram {
file: "ssao.slang",
embedded: SSAO_SLANG,
entry: "ssao_kernel_fragment",
profile: "ps_6_0",
label: "ssao_kernel.slang",
defines: &[("SSAO_KERNEL", "1")],
};
pub(super) static SSAO_BLUR: SlangProgram = SlangProgram {
file: "ssao.slang",
embedded: SSAO_SLANG,
entry: "ssao_blur_fragment",
profile: "ps_6_0",
label: "ssao_blur.slang",
defines: &[("SSAO_BLUR", "1")],
};
pub(super) static SSR_RESOLVE: SlangProgram = SlangProgram {
file: "ssr.slang",
embedded: SSR_SLANG,
entry: "ssr_resolve_fragment",
profile: "ps_6_0",
label: "ssr_resolve.slang",
defines: SSR_DEFINES,
};
pub(super) static SSGI_GATHER: SlangProgram = SlangProgram {
file: "ssgi.slang",
embedded: SSGI_SLANG,
entry: "ssgi_gather_fragment",
profile: "ps_6_0",
label: "ssgi_gather.slang",
defines: &[("SSGI_GATHER", "1")],
};
pub(super) static SSGI_COMPOSITE: SlangProgram = SlangProgram {
file: "ssgi.slang",
embedded: SSGI_SLANG,
entry: "ssgi_composite_fragment",
profile: "ps_6_0",
label: "ssgi_composite.slang",
defines: &[("SSGI_COMPOSITE", "1")],
};
pub(super) static REFLECTION_BLUR: SlangProgram = SlangProgram {
file: "reflection.slang",
embedded: REFLECTION_SLANG,
entry: "reflection_blur_fragment",
profile: "ps_6_0",
label: "reflection_blur.slang",
defines: &[("REFLECTION_BLUR", "1")],
};
pub(super) static REFLECTION_COMPOSITE: SlangProgram = SlangProgram {
file: "reflection.slang",
embedded: REFLECTION_SLANG,
entry: "reflection_composite_fragment",
profile: "ps_6_0",
label: "reflection_composite.slang",
defines: &[("REFLECTION_COMPOSITE", "1")],
};
pub(super) static RT_REFLECTIONS_FRAG: SlangProgram = SlangProgram {
file: "rt_reflections.slang",
embedded: RT_REFLECTIONS_SLANG,
entry: "rt_reflections_fragment",
profile: "ps_6_5",
label: "rt_reflections.slang",
defines: &[("DXIL_ABI", "1"), ("MAX_PROBES", "8")],
};
pub(super) static RT_REFLECTIONS_FRAG_TEXTURED: SlangProgram = SlangProgram {
file: "rt_reflections.slang",
embedded: RT_REFLECTIONS_SLANG,
entry: "rt_reflections_fragment",
profile: "ps_6_5",
label: "rt_reflections_textured.slang",
defines: &[("DXIL_ABI", "1"), ("RT_TEXTURED", "1"), ("MAX_PROBES", "8")],
};
pub(super) static GLASS_VERT: SlangProgram = SlangProgram {
file: "glass.slang",
embedded: GLASS_SLANG,
entry: "glass_vertex",
profile: "vs_6_0",
label: "glass_vert.slang",
defines: &[("DXIL_ABI", "1"), ("MAX_PROBES", "8")],
};
pub(super) static GLASS_FRAG: SlangProgram = SlangProgram {
file: "glass.slang",
embedded: GLASS_SLANG,
entry: "glass_fragment",
profile: "ps_6_0",
label: "glass_frag.slang",
defines: &[("DXIL_ABI", "1"), ("MAX_PROBES", "8"), ("USE_MSAA", "0")],
};
pub(super) static GLASS_FRAG_MSAA: SlangProgram = SlangProgram {
file: "glass.slang",
embedded: GLASS_SLANG,
entry: "glass_fragment",
profile: "ps_6_0",
label: "glass_frag_msaa.slang",
defines: &[("DXIL_ABI", "1"), ("MAX_PROBES", "8"), ("USE_MSAA", "1")],
};
pub(super) static GLASS_RT_FRAG: SlangProgram = SlangProgram {
file: "glass.slang",
embedded: GLASS_SLANG,
entry: "glass_rt_fragment",
profile: "ps_6_5",
label: "glass_frag_rt.slang",
defines: &[
("DXIL_ABI", "1"),
("GLASS_RT", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "0"),
],
};
pub(super) static GLASS_RT_FRAG_MSAA: SlangProgram = SlangProgram {
file: "glass.slang",
embedded: GLASS_SLANG,
entry: "glass_rt_fragment",
profile: "ps_6_5",
label: "glass_frag_rt_msaa.slang",
defines: &[
("DXIL_ABI", "1"),
("GLASS_RT", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "1"),
],
};
pub(super) static GLASS_RT_FRAG_TEXTURED: SlangProgram = SlangProgram {
file: "glass.slang",
embedded: GLASS_SLANG,
entry: "glass_rt_fragment",
profile: "ps_6_5",
label: "glass_frag_rt_textured.slang",
defines: &[
("DXIL_ABI", "1"),
("GLASS_RT", "1"),
("RT_TEXTURED", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "0"),
],
};
pub(super) static GLASS_RT_FRAG_TEXTURED_MSAA: SlangProgram = SlangProgram {
file: "glass.slang",
embedded: GLASS_SLANG,
entry: "glass_rt_fragment",
profile: "ps_6_5",
label: "glass_frag_rt_textured_msaa.slang",
defines: &[
("DXIL_ABI", "1"),
("GLASS_RT", "1"),
("RT_TEXTURED", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "1"),
],
};
const GLASS_MESH_DEFINES: &[(&str, &str)] =
&[("DXIL_ABI", "1"), ("MAX_PROBES", "8"), ("USE_MSAA", "0")];
const GLASS_MESH_MSAA_DEFINES: &[(&str, &str)] =
&[("DXIL_ABI", "1"), ("MAX_PROBES", "8"), ("USE_MSAA", "1")];
const GLASS_MESH_TEXTURED_DEFINES: &[(&str, &str)] = &[
("DXIL_ABI", "1"),
("RT_TEXTURED", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "0"),
];
const GLASS_MESH_TEXTURED_MSAA_DEFINES: &[(&str, &str)] = &[
("DXIL_ABI", "1"),
("RT_TEXTURED", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "1"),
];
pub(super) static GLASS_MESH_VERT: SlangProgram = SlangProgram {
file: "glass_mesh.slang",
embedded: GLASS_MESH_SLANG,
entry: "glass_mesh_vertex",
profile: "vs_6_0",
label: "glass_mesh_vert.slang",
defines: GLASS_MESH_DEFINES,
};
pub(super) static GLASS_MESH_RT_FRAG: SlangProgram = SlangProgram {
file: "glass_mesh.slang",
embedded: GLASS_MESH_SLANG,
entry: "glass_mesh_rt_fragment",
profile: "ps_6_5",
label: "glass_mesh_frag_rt.slang",
defines: GLASS_MESH_DEFINES,
};
pub(super) static GLASS_MESH_RT_FRAG_MSAA: SlangProgram = SlangProgram {
file: "glass_mesh.slang",
embedded: GLASS_MESH_SLANG,
entry: "glass_mesh_rt_fragment",
profile: "ps_6_5",
label: "glass_mesh_frag_rt_msaa.slang",
defines: GLASS_MESH_MSAA_DEFINES,
};
pub(super) static GLASS_MESH_RT_FRAG_TEXTURED: SlangProgram = SlangProgram {
file: "glass_mesh.slang",
embedded: GLASS_MESH_SLANG,
entry: "glass_mesh_rt_fragment",
profile: "ps_6_5",
label: "glass_mesh_frag_rt_textured.slang",
defines: GLASS_MESH_TEXTURED_DEFINES,
};
pub(super) static GLASS_MESH_RT_FRAG_TEXTURED_MSAA: SlangProgram = SlangProgram {
file: "glass_mesh.slang",
embedded: GLASS_MESH_SLANG,
entry: "glass_mesh_rt_fragment",
profile: "ps_6_5",
label: "glass_mesh_frag_rt_textured_msaa.slang",
defines: GLASS_MESH_TEXTURED_MSAA_DEFINES,
};
pub(super) static WATER_VERT: SlangProgram = SlangProgram {
file: "water.slang",
embedded: WATER_SLANG,
entry: "water_vertex",
profile: "vs_6_0",
label: "water_vert.slang",
defines: &[("DXIL_ABI", "1"), ("MAX_PROBES", "8")],
};
pub(super) static WATER_FRAG: SlangProgram = SlangProgram {
file: "water.slang",
embedded: WATER_SLANG,
entry: "water_fragment",
profile: "ps_6_0",
label: "water_frag.slang",
defines: &[("DXIL_ABI", "1"), ("MAX_PROBES", "8"), ("USE_MSAA", "0")],
};
pub(super) static WATER_FRAG_MSAA: SlangProgram = SlangProgram {
file: "water.slang",
embedded: WATER_SLANG,
entry: "water_fragment",
profile: "ps_6_0",
label: "water_frag_msaa.slang",
defines: &[("DXIL_ABI", "1"), ("MAX_PROBES", "8"), ("USE_MSAA", "1")],
};
pub(super) static WATER_RT_FRAG: SlangProgram = SlangProgram {
file: "water.slang",
embedded: WATER_SLANG,
entry: "water_rt_fragment",
profile: "ps_6_5",
label: "water_frag_rt.slang",
defines: &[
("DXIL_ABI", "1"),
("WATER_RT", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "0"),
],
};
pub(super) static WATER_RT_FRAG_MSAA: SlangProgram = SlangProgram {
file: "water.slang",
embedded: WATER_SLANG,
entry: "water_rt_fragment",
profile: "ps_6_5",
label: "water_frag_rt_msaa.slang",
defines: &[
("DXIL_ABI", "1"),
("WATER_RT", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "1"),
],
};
pub(super) static WATER_RT_FRAG_TEXTURED: SlangProgram = SlangProgram {
file: "water.slang",
embedded: WATER_SLANG,
entry: "water_rt_fragment",
profile: "ps_6_5",
label: "water_frag_rt_textured.slang",
defines: &[
("DXIL_ABI", "1"),
("WATER_RT", "1"),
("RT_TEXTURED", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "0"),
],
};
pub(super) static WATER_RT_FRAG_TEXTURED_MSAA: SlangProgram = SlangProgram {
file: "water.slang",
embedded: WATER_SLANG,
entry: "water_rt_fragment",
profile: "ps_6_5",
label: "water_frag_rt_textured_msaa.slang",
defines: &[
("DXIL_ABI", "1"),
("WATER_RT", "1"),
("RT_TEXTURED", "1"),
("MAX_PROBES", "8"),
("USE_MSAA", "1"),
],
};
const PARTICLE_ABI: &[(&str, &str)] = &[("DXIL_ABI", "1")];
pub(super) static PARTICLE_VERT: SlangProgram = SlangProgram {
file: "particle.slang",
embedded: PARTICLE_SLANG,
entry: "particle_vertex",
profile: "vs_6_0",
label: "particle_vert.slang",
defines: PARTICLE_ABI,
};
pub(super) static PARTICLE_FRAG: SlangProgram = SlangProgram {
file: "particle.slang",
embedded: PARTICLE_SLANG,
entry: "particle_fragment",
profile: "ps_6_0",
label: "particle_frag.slang",
defines: PARTICLE_ABI,
};
pub(super) static DECAL_VERT: SlangProgram = SlangProgram {
file: "decal.slang",
embedded: DECAL_SLANG,
entry: "decal_vertex",
profile: "vs_6_0",
label: "decal_vert.slang",
defines: &[],
};
pub(super) static DECAL_FRAG: SlangProgram = SlangProgram {
file: "decal.slang",
embedded: DECAL_SLANG,
entry: "decal_fragment",
profile: "ps_6_0",
label: "decal_frag.slang",
defines: &[("USE_MSAA", "0")],
};
pub(super) static DECAL_FRAG_MSAA: SlangProgram = SlangProgram {
file: "decal.slang",
embedded: DECAL_SLANG,
entry: "decal_fragment",
profile: "ps_6_0",
label: "decal_frag_msaa.slang",
defines: &[("USE_MSAA", "1")],
};
pub(super) static LINE_VERT: SlangProgram = SlangProgram {
file: "line.slang",
embedded: LINE_SLANG,
entry: "line_vertex",
profile: "vs_6_0",
label: "line_vert.slang",
defines: &[],
};
pub(super) static LINE_FRAG: SlangProgram = SlangProgram {
file: "line.slang",
embedded: LINE_SLANG,
entry: "line_fragment",
profile: "ps_6_0",
label: "line_frag.slang",
defines: &[("USE_MSAA", "0")],
};
pub(super) static LINE_FRAG_MSAA: SlangProgram = SlangProgram {
file: "line.slang",
embedded: LINE_SLANG,
entry: "line_fragment",
profile: "ps_6_0",
label: "line_frag_msaa.slang",
defines: &[("USE_MSAA", "1")],
};
pub(super) static TEXT_VERT: SlangProgram = SlangProgram {
file: "text.slang",
embedded: TEXT_SLANG,
entry: "text_vertex_main",
profile: "vs_6_0",
label: "text_vert.slang",
defines: &[],
};
pub(super) static TEXT_FRAG: SlangProgram = SlangProgram {
file: "text.slang",
embedded: TEXT_SLANG,
entry: "text_fragment_main",
profile: "ps_6_0",
label: "text_frag.slang",
defines: &[],
};
pub(crate) static ALL: &[&SlangProgram] = &[
&MAIN_BINDLESS_VERT,
&MAIN_BINDLESS_FRAG,
&LIGHT_CULL,
&RT_SKIN,
&HIZ_INIT_SINGLE,
&HIZ_INIT_MSAA,
&HIZ_DOWNSAMPLE,
&GBUFFER_PREPASS_VERT,
&GBUFFER_PREPASS_VERT_INSTANCED,
&GBUFFER_PREPASS_VERT_SKINNED,
&GBUFFER_BINDLESS_VERT,
&GBUFFER_PREPASS_FRAG,
&GBUFFER_BINDLESS_FRAG,
&SHADOW_VERT,
&SKINNED_SHADOW_VERT,
&SHADOW_BINDLESS_VERT,
&FOG_FROXEL,
&FOG_FRAG,
&FOG_FRAG_MSAA,
&AUTO_EXPOSURE_BUILD,
&AUTO_EXPOSURE_AVERAGE,
&PARTICLE_SIMULATE,
&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,
&RT_REFLECTIONS_FRAG,
&RT_REFLECTIONS_FRAG_TEXTURED,
&GLASS_VERT,
&GLASS_FRAG,
&GLASS_FRAG_MSAA,
&GLASS_RT_FRAG,
&GLASS_RT_FRAG_MSAA,
&GLASS_RT_FRAG_TEXTURED,
&GLASS_RT_FRAG_TEXTURED_MSAA,
&GLASS_MESH_VERT,
&GLASS_MESH_RT_FRAG,
&GLASS_MESH_RT_FRAG_MSAA,
&GLASS_MESH_RT_FRAG_TEXTURED,
&GLASS_MESH_RT_FRAG_TEXTURED_MSAA,
&WATER_VERT,
&WATER_FRAG,
&WATER_FRAG_MSAA,
&WATER_RT_FRAG,
&WATER_RT_FRAG_MSAA,
&WATER_RT_FRAG_TEXTURED,
&WATER_RT_FRAG_TEXTURED_MSAA,
&PARTICLE_VERT,
&PARTICLE_FRAG,
&DECAL_VERT,
&DECAL_FRAG,
&DECAL_FRAG_MSAA,
&LINE_VERT,
&LINE_FRAG,
&LINE_FRAG_MSAA,
&TEXT_VERT,
&TEXT_FRAG,
];
impl SlangProgram {
pub(crate) fn source(&self, hot_reload: bool) -> String {
crate::slang_source::assemble(hot_reload, self.file, self.embedded, self.defines)
}
fn target(&self) -> slang::SlangTarget {
slang::SlangTarget::Dxil(self.profile)
}
pub(crate) fn cache_key<'a>(&self, source: &'a str) -> crate::shader_cache::Key<'a> {
crate::shader_cache::Key {
compiler: "slang",
source,
entry: self.entry,
target: self.profile,
options: 0,
}
}
pub(crate) fn compile(&self, hot_reload: bool) -> Result<Vec<u8>, String> {
let source = self.source(hot_reload);
let key = self.cache_key(&source);
crate::shader_cache::cached(&key, self.label, || compile_uncached(self, &source))
}
}
pub(super) fn compile_uncached(program: &SlangProgram, source: &str) -> Result<Vec<u8>, String> {
let job = slang::SlangJob {
source,
file_name: program.file,
entries: &[program.entry],
target: program.target(),
};
slang::compile(&job, &crate::shader_cache::slang_work_dir())
}
pub(crate) fn precompile(out_dir: &std::path::Path, report: &mut crate::precompile::Report) {
for program in ALL {
let source = program.source(false);
let key = program.cache_key(&source);
report.record(
&format!("{} {}", program.entry, program.profile),
crate::shader_cache::ensure_in(out_dir, &key, || compile_uncached(program, &source)),
);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn variant_gates_and_abi_define_lead_the_source() {
assert!(
MAIN_BINDLESS_FRAG
.source(false)
.starts_with("#define DXIL_ABI 1\n#define MAX_PROBES 8\n")
);
assert!(
HIZ_INIT_MSAA
.source(false)
.starts_with("#define HIZ_INIT_MSAA 1\n")
);
assert!(
SSR_RESOLVE
.source(false)
.starts_with("#define MAX_PROBES 8\n")
);
assert!(!LIGHT_CULL.source(false).starts_with("#define"));
}
#[test]
fn every_program_assembles_with_its_fragments_spliced() {
for p in ALL {
let src = p.source(false);
for marker in [
"{POST_COMMON}",
"{OBJECT_COMMON}",
"{PROBE_TYPES}",
"{PROBE_COMMON}",
"{RT_TYPES}",
"{RT_TRACE}",
"{PARTICLE_TYPES}",
] {
assert!(
!src.contains(marker),
"{}: unspliced fragment marker {marker}",
p.label
);
}
}
}
#[test]
fn the_prepass_pins_sky_to_the_far_plane() {
assert!(GBUFFER_PREPASS_SLANG.contains("color.b > 1.5"));
assert!(GBUFFER_PREPASS_SLANG.contains("position.z = position.w"));
assert_eq!(GBUFFER_PREPASS_SLANG.matches("gb_sky_pin(").count(), 3);
}
#[test]
fn table_has_no_duplicate_programs() {
let mut seen = std::collections::HashSet::new();
for p in ALL {
assert!(
seen.insert((p.source(false), p.entry, p.profile)),
"duplicate program: {}",
p.label
);
}
}
#[test]
fn the_cache_key_tracks_the_program() {
let src = MAIN_BINDLESS_VERT.source(false);
let key = MAIN_BINDLESS_VERT.cache_key(&src);
assert_eq!(key.compiler, "slang");
assert_eq!(key.entry, "vertex_main_bindless");
assert_eq!(key.target, "vs_6_0");
assert_eq!(MAIN_BINDLESS_FRAG.cache_key(&src).target, "ps_6_0");
}
#[test]
fn probe_cube_count_matches_the_host_constant() {
let want = concinnity_render::uniforms::MAX_PROBES.to_string();
let mut sized = 0usize;
for p in ALL {
for (key, value) in p.defines {
if *key == "MAX_PROBES" {
assert_eq!(*value, want.as_str(), "{}", p.label);
sized += 1;
}
}
}
assert!(sized > 0, "no program bakes MAX_PROBES in");
}
#[test]
fn reflection_roughness_cut_matches_canonical() {
let expected = format!(
"static const float REFLECTION_ROUGHNESS_CUT = {:?};",
crate::gfx::ssr::REFLECTION_ROUGHNESS_CUT
);
for (name, src) in [
("main_bindless.slang", MAIN_BINDLESS_SLANG),
("ssr.slang", SSR_SLANG),
("reflection.slang", REFLECTION_SLANG),
("rt_reflections.slang", RT_REFLECTIONS_SLANG),
] {
assert!(
src.contains(&expected),
"{name} REFLECTION_ROUGHNESS_CUT drifted from \
concinnity_core::gfx::ssr::REFLECTION_ROUGHNESS_CUT"
);
}
}
#[test]
fn cluster_constants_match_render_types() {
use crate::gfx::render_types::{CLUSTER_LIGHT_LIST_STRIDE, MAX_LIGHTS_PER_CLUSTER};
for src in [LIGHT_CULL_SLANG, MAIN_BINDLESS_SLANG] {
assert!(src.contains(&format!(
"CLUSTER_LIGHT_LIST_STRIDE = {CLUSTER_LIGHT_LIST_STRIDE}u"
)));
}
assert!(LIGHT_CULL_SLANG.contains(&format!(
"MAX_LIGHTS_PER_CLUSTER = {MAX_LIGHTS_PER_CLUSTER}u"
)));
}
#[test]
fn the_bindless_vertex_path_pins_sky_to_the_far_plane() {
assert!(MAIN_BINDLESS_SLANG.contains("v.color.b > 1.5"));
assert!(MAIN_BINDLESS_SLANG.contains("o.position.z = o.position.w"));
}
}