1#[derive(Clone, Copy, PartialEq, Eq)]
19pub enum Sizes {
20 None,
22 Probes,
25 PoolAndProbes,
27}
28
29pub struct SlangProgram {
32 pub file: &'static str,
35 pub entry: &'static str,
37 pub label: &'static str,
39 pub gates: &'static [&'static str],
43 pub sizes: Sizes,
45 pub msaa: bool,
49}
50
51pub static MAIN_BINDLESS_VERT: SlangProgram = SlangProgram {
53 file: "main_bindless.slang",
54 entry: "vertex_main_bindless",
55 label: "vert_bindless.slang",
56 gates: &[],
57 sizes: Sizes::PoolAndProbes,
58 msaa: false,
59};
60pub static MAIN_BINDLESS_FRAG: SlangProgram = SlangProgram {
62 file: "main_bindless.slang",
63 entry: "fragment_main_bindless",
64 label: "frag_bindless.slang",
65 gates: &[],
66 sizes: Sizes::PoolAndProbes,
67 msaa: false,
68};
69pub static CULL: SlangProgram = SlangProgram {
71 file: "cull.slang",
72 entry: "cull_kernel",
73 label: "cull.slang",
74 gates: &[],
75 sizes: Sizes::None,
76 msaa: false,
77};
78pub static CULL_PHASE2: SlangProgram = SlangProgram {
81 file: "cull.slang",
82 entry: "cull_kernel",
83 label: "cull_phase2.slang",
84 gates: &["CULL_PHASE2"],
85 sizes: Sizes::None,
86 msaa: false,
87};
88pub static CULL_SHADOW: SlangProgram = SlangProgram {
91 file: "cull.slang",
92 entry: "cull_kernel",
93 label: "cull_shadow.slang",
94 gates: &["SHADOW_CULL"],
95 sizes: Sizes::None,
96 msaa: false,
97};
98pub static MODEL_HISTORY: SlangProgram = SlangProgram {
101 file: "model_history.slang",
102 entry: "model_history_kernel",
103 label: "model_history.slang",
104 gates: &[],
105 sizes: Sizes::None,
106 msaa: false,
107};
108pub static LIGHT_CULL: SlangProgram = SlangProgram {
110 file: "light_cull.slang",
111 entry: "light_cull_kernel",
112 label: "light_cull.slang",
113 gates: &[],
114 sizes: Sizes::None,
115 msaa: false,
116};
117pub static HIZ_INIT_MSAA: SlangProgram = SlangProgram {
119 file: "hiz_build.slang",
120 entry: "hiz_init_msaa",
121 label: "hiz_init_msaa.slang",
122 gates: &["HIZ_INIT_MSAA"],
123 sizes: Sizes::None,
124 msaa: false,
125};
126pub static HIZ_INIT_SINGLE: SlangProgram = SlangProgram {
128 file: "hiz_build.slang",
129 entry: "hiz_init_single",
130 label: "hiz_init_single.slang",
131 gates: &["HIZ_INIT_SINGLE"],
132 sizes: Sizes::None,
133 msaa: false,
134};
135pub static HIZ_DOWNSAMPLE: SlangProgram = SlangProgram {
137 file: "hiz_build.slang",
138 entry: "hiz_downsample",
139 label: "hiz_downsample.slang",
140 gates: &["HIZ_DOWNSAMPLE"],
141 sizes: Sizes::None,
142 msaa: false,
143};
144pub static HIZ_SPD_MSAA: SlangProgram = SlangProgram {
146 file: "hiz_build.slang",
147 entry: "hiz_spd_msaa",
148 label: "hiz_spd_msaa.slang",
149 gates: &["HIZ_SPD_MSAA"],
150 sizes: Sizes::None,
151 msaa: false,
152};
153pub static HIZ_SPD_SINGLE: SlangProgram = SlangProgram {
155 file: "hiz_build.slang",
156 entry: "hiz_spd_single",
157 label: "hiz_spd_single.slang",
158 gates: &["HIZ_SPD_SINGLE"],
159 sizes: Sizes::None,
160 msaa: false,
161};
162pub static HIZ_SPD_TAIL: SlangProgram = SlangProgram {
164 file: "hiz_build.slang",
165 entry: "hiz_spd_tail",
166 label: "hiz_spd_tail.slang",
167 gates: &["HIZ_SPD_TAIL"],
168 sizes: Sizes::None,
169 msaa: false,
170};
171
172pub static PROBE_MIP0: SlangProgram = SlangProgram {
174 file: "probe_prefilter.slang",
175 entry: "probe_mip0",
176 label: "probe_mip0.slang",
177 gates: &["PROBE_MIP0"],
178 sizes: Sizes::None,
179 msaa: false,
180};
181pub static PROBE_DOWNSAMPLE: SlangProgram = SlangProgram {
183 file: "probe_prefilter.slang",
184 entry: "probe_downsample",
185 label: "probe_downsample.slang",
186 gates: &["PROBE_DOWNSAMPLE"],
187 sizes: Sizes::None,
188 msaa: false,
189};
190pub static PROBE_GGX: SlangProgram = SlangProgram {
192 file: "probe_prefilter.slang",
193 entry: "probe_ggx",
194 label: "probe_ggx.slang",
195 gates: &["PROBE_GGX"],
196 sizes: Sizes::None,
197 msaa: false,
198};
199
200pub static GBUFFER_BINDLESS_VERT: SlangProgram = SlangProgram {
206 file: "gbuffer_prepass.slang",
207 entry: "gbuffer_prepass_vertex_bindless",
208 label: "gbuffer_prepass_vert_bindless.slang",
209 gates: &["GB_BINDLESS"],
210 sizes: Sizes::None,
211 msaa: false,
212};
213pub static GBUFFER_BINDLESS_FRAG: SlangProgram = SlangProgram {
215 file: "gbuffer_prepass.slang",
216 entry: "gbuffer_prepass_fragment_bindless",
217 label: "gbuffer_prepass_frag_bindless.slang",
218 gates: &["GB_FRAGMENT_BINDLESS"],
219 sizes: Sizes::None,
220 msaa: false,
221};
222pub static SHADOW_VERT: SlangProgram = SlangProgram {
224 file: "shadow.slang",
225 entry: "shadow_vertex_main",
226 label: "shadow_vert.slang",
227 gates: &["SHADOW_STATIC"],
228 sizes: Sizes::None,
229 msaa: false,
230};
231pub static SKINNED_SHADOW_VERT: SlangProgram = SlangProgram {
233 file: "shadow.slang",
234 entry: "shadow_vertex_main_skinned",
235 label: "shadow_vert_skinned.slang",
236 gates: &["SHADOW_SKINNED"],
237 sizes: Sizes::None,
238 msaa: false,
239};
240pub static SHADOW_BINDLESS_VERT: SlangProgram = SlangProgram {
242 file: "shadow.slang",
243 entry: "shadow_vertex_bindless",
244 label: "shadow_vert_bindless.slang",
245 gates: &["SHADOW_BINDLESS"],
246 sizes: Sizes::None,
247 msaa: false,
248};
249
250pub static FULLSCREEN_VERT: SlangProgram = SlangProgram {
254 file: "fullscreen.slang",
255 entry: "fullscreen_vertex",
256 label: "fullscreen_vert.slang",
257 gates: &[],
258 sizes: Sizes::None,
259 msaa: false,
260};
261pub static TAA_FRAG: SlangProgram = SlangProgram {
263 file: "taa.slang",
264 entry: "taa_fragment_main",
265 label: "taa_frag.slang",
266 gates: &[],
267 sizes: Sizes::None,
268 msaa: false,
269};
270pub static BLOOM_PREFILTER: SlangProgram = SlangProgram {
272 file: "bloom.slang",
273 entry: "bloom_prefilter_fragment",
274 label: "bloom_prefilter.slang",
275 gates: &["BLOOM_PREFILTER"],
276 sizes: Sizes::None,
277 msaa: false,
278};
279pub static BLOOM_DOWNSAMPLE: SlangProgram = SlangProgram {
281 file: "bloom.slang",
282 entry: "bloom_downsample_fragment",
283 label: "bloom_downsample.slang",
284 gates: &["BLOOM_DOWNSAMPLE"],
285 sizes: Sizes::None,
286 msaa: false,
287};
288pub static BLOOM_UPSAMPLE: SlangProgram = SlangProgram {
290 file: "bloom.slang",
291 entry: "bloom_upsample_fragment",
292 label: "bloom_upsample.slang",
293 gates: &["BLOOM_UPSAMPLE"],
294 sizes: Sizes::None,
295 msaa: false,
296};
297pub static COMPOSITE_FRAG: SlangProgram = SlangProgram {
299 file: "composite.slang",
300 entry: "composite_fragment",
301 label: "composite_frag.slang",
302 gates: &[],
303 sizes: Sizes::None,
304 msaa: false,
305};
306pub static SSAO_KERNEL: SlangProgram = SlangProgram {
308 file: "ssao.slang",
309 entry: "ssao_kernel_fragment",
310 label: "ssao_kernel.slang",
311 gates: &["SSAO_KERNEL"],
312 sizes: Sizes::None,
313 msaa: false,
314};
315pub static SSAO_BLUR: SlangProgram = SlangProgram {
317 file: "ssao.slang",
318 entry: "ssao_blur_fragment",
319 label: "ssao_blur.slang",
320 gates: &["SSAO_BLUR"],
321 sizes: Sizes::None,
322 msaa: false,
323};
324pub static SSR_RESOLVE: SlangProgram = SlangProgram {
326 file: "ssr.slang",
327 entry: "ssr_resolve_fragment",
328 label: "ssr_resolve.slang",
329 gates: &[],
330 sizes: Sizes::Probes,
331 msaa: false,
332};
333pub static SSGI_GATHER: SlangProgram = SlangProgram {
335 file: "ssgi.slang",
336 entry: "ssgi_gather_fragment",
337 label: "ssgi_gather.slang",
338 gates: &["SSGI_GATHER"],
339 sizes: Sizes::None,
340 msaa: false,
341};
342pub static SSGI_COMPOSITE: SlangProgram = SlangProgram {
344 file: "ssgi.slang",
345 entry: "ssgi_composite_fragment",
346 label: "ssgi_composite.slang",
347 gates: &["SSGI_COMPOSITE"],
348 sizes: Sizes::None,
349 msaa: false,
350};
351pub static REFLECTION_BLUR: SlangProgram = SlangProgram {
353 file: "reflection.slang",
354 entry: "reflection_blur_fragment",
355 label: "reflection_blur.slang",
356 gates: &["REFLECTION_BLUR"],
357 sizes: Sizes::None,
358 msaa: false,
359};
360pub static REFLECTION_COMPOSITE: SlangProgram = SlangProgram {
362 file: "reflection.slang",
363 entry: "reflection_composite_fragment",
364 label: "reflection_composite.slang",
365 gates: &["REFLECTION_COMPOSITE"],
366 sizes: Sizes::None,
367 msaa: false,
368};
369
370pub static FOG_FROXEL: SlangProgram = SlangProgram {
374 file: "fog.slang",
375 entry: "fog_froxel_kernel",
376 label: "fog_froxel.slang",
377 gates: &["FOG_FROXEL"],
378 sizes: Sizes::None,
379 msaa: false,
380};
381pub static FOG_FRAG: SlangProgram = SlangProgram {
383 file: "fog.slang",
384 entry: "fog_fragment",
385 label: "fog_frag.slang",
386 gates: &[],
387 sizes: Sizes::None,
388 msaa: true,
389};
390pub static AUTO_EXPOSURE_BUILD: SlangProgram = SlangProgram {
392 file: "auto_exposure.slang",
393 entry: "histogram_build",
394 label: "auto_exposure_build.slang",
395 gates: &["AE_BUILD"],
396 sizes: Sizes::None,
397 msaa: false,
398};
399pub static AUTO_EXPOSURE_AVERAGE: SlangProgram = SlangProgram {
401 file: "auto_exposure.slang",
402 entry: "histogram_average",
403 label: "auto_exposure_average.slang",
404 gates: &["AE_AVERAGE"],
405 sizes: Sizes::None,
406 msaa: false,
407};
408pub static RT_SKIN: SlangProgram = SlangProgram {
410 file: "rt_skin.slang",
411 entry: "rt_skin",
412 label: "rt_skin.slang",
413 gates: &[],
414 sizes: Sizes::None,
415 msaa: false,
416};
417pub static PARTICLE_SIMULATE: SlangProgram = SlangProgram {
419 file: "particle_simulate.slang",
420 entry: "particle_simulate",
421 label: "particle_simulate.slang",
422 gates: &[],
423 sizes: Sizes::None,
424 msaa: false,
425};
426
427pub static PARTICLE_VERT: SlangProgram = SlangProgram {
434 file: "particle.slang",
435 entry: "particle_vertex",
436 label: "particle_vert.slang",
437 gates: &[],
438 sizes: Sizes::None,
439 msaa: false,
440};
441pub static PARTICLE_FRAG: SlangProgram = SlangProgram {
443 file: "particle.slang",
444 entry: "particle_fragment",
445 label: "particle_frag.slang",
446 gates: &[],
447 sizes: Sizes::None,
448 msaa: false,
449};
450pub static DECAL_VERT: SlangProgram = SlangProgram {
452 file: "decal.slang",
453 entry: "decal_vertex",
454 label: "decal_vert.slang",
455 gates: &[],
456 sizes: Sizes::None,
457 msaa: false,
458};
459pub static DECAL_FRAG: SlangProgram = SlangProgram {
461 file: "decal.slang",
462 entry: "decal_fragment",
463 label: "decal_frag.slang",
464 gates: &[],
465 sizes: Sizes::None,
466 msaa: true,
467};
468pub static LINE_VERT: SlangProgram = SlangProgram {
470 file: "line.slang",
471 entry: "line_vertex",
472 label: "line_vert.slang",
473 gates: &[],
474 sizes: Sizes::None,
475 msaa: false,
476};
477pub static LINE_FRAG: SlangProgram = SlangProgram {
479 file: "line.slang",
480 entry: "line_fragment",
481 label: "line_frag.slang",
482 gates: &[],
483 sizes: Sizes::None,
484 msaa: true,
485};
486pub static TEXT_VERT: SlangProgram = SlangProgram {
488 file: "text.slang",
489 entry: "text_vertex_main",
490 label: "text_vert.slang",
491 gates: &[],
492 sizes: Sizes::None,
493 msaa: false,
494};
495pub static TEXT_FRAG: SlangProgram = SlangProgram {
497 file: "text.slang",
498 entry: "text_fragment_main",
499 label: "text_frag.slang",
500 gates: &[],
501 sizes: Sizes::None,
502 msaa: false,
503};
504
505pub static RT_REFLECTIONS_FRAG: SlangProgram = SlangProgram {
513 file: "rt_reflections.slang",
514 entry: "rt_reflections_fragment",
515 label: "rt_reflections.slang",
516 gates: &[],
517 sizes: Sizes::Probes,
518 msaa: false,
519};
520pub static RT_REFLECTIONS_FRAG_TEXTURED: SlangProgram = SlangProgram {
522 file: "rt_reflections.slang",
523 entry: "rt_reflections_fragment",
524 label: "rt_reflections_textured.slang",
525 gates: &["RT_TEXTURED"],
526 sizes: Sizes::PoolAndProbes,
527 msaa: false,
528};
529pub static GLASS_VERT: SlangProgram = SlangProgram {
531 file: "glass.slang",
532 entry: "glass_vertex",
533 label: "glass_vert.slang",
534 gates: &[],
535 sizes: Sizes::Probes,
536 msaa: true,
537};
538pub static GLASS_FRAG: SlangProgram = SlangProgram {
540 file: "glass.slang",
541 entry: "glass_fragment",
542 label: "glass_frag.slang",
543 gates: &[],
544 sizes: Sizes::Probes,
545 msaa: true,
546};
547pub static GLASS_FRAG_RT: SlangProgram = SlangProgram {
549 file: "glass.slang",
550 entry: "glass_rt_fragment",
551 label: "glass_frag_rt.slang",
552 gates: &["GLASS_RT"],
553 sizes: Sizes::Probes,
554 msaa: true,
555};
556pub static GLASS_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
558 file: "glass.slang",
559 entry: "glass_rt_fragment",
560 label: "glass_frag_rt_textured.slang",
561 gates: &["GLASS_RT", "RT_TEXTURED"],
562 sizes: Sizes::PoolAndProbes,
563 msaa: true,
564};
565
566pub static GLASS_MESH_VERT: SlangProgram = SlangProgram {
573 file: "glass_mesh.slang",
574 entry: "glass_mesh_vertex",
575 label: "glass_mesh_vert.slang",
576 gates: &[],
577 sizes: Sizes::Probes,
578 msaa: true,
579};
580pub static GLASS_MESH_FRAG_RT: SlangProgram = SlangProgram {
582 file: "glass_mesh.slang",
583 entry: "glass_mesh_rt_fragment",
584 label: "glass_mesh_frag_rt.slang",
585 gates: &[],
586 sizes: Sizes::Probes,
587 msaa: true,
588};
589pub static GLASS_MESH_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
591 file: "glass_mesh.slang",
592 entry: "glass_mesh_rt_fragment",
593 label: "glass_mesh_frag_rt_textured.slang",
594 gates: &["RT_TEXTURED"],
595 sizes: Sizes::PoolAndProbes,
596 msaa: true,
597};
598
599pub static WATER_VERT: SlangProgram = SlangProgram {
605 file: "water.slang",
606 entry: "water_vertex",
607 label: "water_vert.slang",
608 gates: &[],
609 sizes: Sizes::Probes,
610 msaa: true,
611};
612pub static WATER_FRAG: SlangProgram = SlangProgram {
614 file: "water.slang",
615 entry: "water_fragment",
616 label: "water_frag.slang",
617 gates: &[],
618 sizes: Sizes::Probes,
619 msaa: true,
620};
621pub static WATER_FRAG_RT: SlangProgram = SlangProgram {
623 file: "water.slang",
624 entry: "water_rt_fragment",
625 label: "water_frag_rt.slang",
626 gates: &["WATER_RT"],
627 sizes: Sizes::Probes,
628 msaa: true,
629};
630pub static WATER_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
632 file: "water.slang",
633 entry: "water_rt_fragment",
634 label: "water_frag_rt_textured.slang",
635 gates: &["WATER_RT", "RT_TEXTURED"],
636 sizes: Sizes::PoolAndProbes,
637 msaa: true,
638};
639
640pub static ALL: &[&SlangProgram] = &[
644 &MAIN_BINDLESS_VERT,
645 &MAIN_BINDLESS_FRAG,
646 &LIGHT_CULL,
647 &MODEL_HISTORY,
648 &CULL,
649 &CULL_PHASE2,
650 &CULL_SHADOW,
651 &RT_SKIN,
652 &HIZ_INIT_MSAA,
653 &HIZ_INIT_SINGLE,
654 &HIZ_DOWNSAMPLE,
655 &PROBE_MIP0,
656 &PROBE_DOWNSAMPLE,
657 &PROBE_GGX,
658 &GBUFFER_BINDLESS_VERT,
659 &GBUFFER_BINDLESS_FRAG,
660 &SHADOW_VERT,
661 &SKINNED_SHADOW_VERT,
662 &SHADOW_BINDLESS_VERT,
663 &FULLSCREEN_VERT,
664 &TAA_FRAG,
665 &BLOOM_PREFILTER,
666 &BLOOM_DOWNSAMPLE,
667 &BLOOM_UPSAMPLE,
668 &COMPOSITE_FRAG,
669 &SSAO_KERNEL,
670 &SSAO_BLUR,
671 &SSR_RESOLVE,
672 &SSGI_GATHER,
673 &SSGI_COMPOSITE,
674 &REFLECTION_BLUR,
675 &REFLECTION_COMPOSITE,
676 &FOG_FROXEL,
677 &FOG_FRAG,
678 &AUTO_EXPOSURE_BUILD,
679 &AUTO_EXPOSURE_AVERAGE,
680 &PARTICLE_SIMULATE,
681 &PARTICLE_VERT,
682 &PARTICLE_FRAG,
683 &DECAL_VERT,
684 &DECAL_FRAG,
685 &LINE_VERT,
686 &LINE_FRAG,
687 &TEXT_VERT,
688 &TEXT_FRAG,
689 &RT_REFLECTIONS_FRAG,
690 &RT_REFLECTIONS_FRAG_TEXTURED,
691 &GLASS_VERT,
692 &GLASS_FRAG,
693 &GLASS_FRAG_RT,
694 &GLASS_FRAG_RT_TEXTURED,
695 &GLASS_MESH_VERT,
696 &GLASS_MESH_FRAG_RT,
697 &GLASS_MESH_FRAG_RT_TEXTURED,
698 &WATER_VERT,
699 &WATER_FRAG,
700 &WATER_FRAG_RT,
701 &WATER_FRAG_RT_TEXTURED,
702];
703
704#[cfg(test)]
705mod tests {
706 use super::*;
707 use alloc::vec::Vec;
708
709 #[test]
713 fn every_program_has_a_distinct_label() {
714 let mut labels: Vec<&str> = ALL.iter().map(|p| p.label).collect();
715 let declared = labels.len();
716 labels.sort_unstable();
717 labels.dedup();
718 assert_eq!(
719 labels.len(),
720 declared,
721 "two programs share a label, so they would share a precompiled artifact"
722 );
723 }
724
725 #[test]
726 fn every_program_names_an_embedded_shader() {
727 for p in ALL {
728 assert!(
729 crate::render::shaders::embedded(p.file).is_some(),
730 "{}: no embedded {}",
731 p.label,
732 p.file
733 );
734 }
735 }
736
737 #[test]
741 fn the_only_per_host_variant_is_the_sample_count() {
742 let sampled = ALL.iter().filter(|p| p.msaa).count();
743 assert!(sampled > 0, "the MSAA dimension went missing");
744 assert!(sampled < ALL.len(), "every program cannot read the depth");
745 for p in ALL {
746 assert!(!p.entry.is_empty(), "{}", p.label);
747 }
748 }
749}