1#[derive(Clone, Copy, PartialEq, Eq)]
20pub enum Sizes {
22 None,
24 Probes,
27 PoolAndProbes,
29}
30
31pub struct SlangProgram {
34 pub file: &'static str,
37 pub entry: &'static str,
39 pub label: &'static str,
41 pub gates: &'static [&'static str],
45 pub sizes: Sizes,
47 pub msaa: bool,
51}
52
53pub static MAIN_BINDLESS_VERT: SlangProgram = SlangProgram {
55 file: "main_bindless.slang",
56 entry: "vertex_main_bindless",
57 label: "vert_bindless.slang",
58 gates: &[],
59 sizes: Sizes::PoolAndProbes,
60 msaa: false,
61};
62pub static MAIN_BINDLESS_FRAG: SlangProgram = SlangProgram {
64 file: "main_bindless.slang",
65 entry: "fragment_main_bindless",
66 label: "frag_bindless.slang",
67 gates: &[],
68 sizes: Sizes::PoolAndProbes,
69 msaa: false,
70};
71pub static LIGHT_CULL: SlangProgram = SlangProgram {
73 file: "light_cull.slang",
74 entry: "light_cull_kernel",
75 label: "light_cull.slang",
76 gates: &[],
77 sizes: Sizes::None,
78 msaa: false,
79};
80pub static HIZ_INIT_MSAA: SlangProgram = SlangProgram {
82 file: "hiz_build.slang",
83 entry: "hiz_init_msaa",
84 label: "hiz_init_msaa.slang",
85 gates: &["HIZ_INIT_MSAA"],
86 sizes: Sizes::None,
87 msaa: false,
88};
89pub static HIZ_INIT_SINGLE: SlangProgram = SlangProgram {
91 file: "hiz_build.slang",
92 entry: "hiz_init_single",
93 label: "hiz_init_single.slang",
94 gates: &["HIZ_INIT_SINGLE"],
95 sizes: Sizes::None,
96 msaa: false,
97};
98pub static HIZ_DOWNSAMPLE: SlangProgram = SlangProgram {
100 file: "hiz_build.slang",
101 entry: "hiz_downsample",
102 label: "hiz_downsample.slang",
103 gates: &["HIZ_DOWNSAMPLE"],
104 sizes: Sizes::None,
105 msaa: false,
106};
107
108pub static PROBE_MIP0: SlangProgram = SlangProgram {
110 file: "probe_prefilter.slang",
111 entry: "probe_mip0",
112 label: "probe_mip0.slang",
113 gates: &["PROBE_MIP0"],
114 sizes: Sizes::None,
115 msaa: false,
116};
117pub static PROBE_DOWNSAMPLE: SlangProgram = SlangProgram {
119 file: "probe_prefilter.slang",
120 entry: "probe_downsample",
121 label: "probe_downsample.slang",
122 gates: &["PROBE_DOWNSAMPLE"],
123 sizes: Sizes::None,
124 msaa: false,
125};
126pub static PROBE_GGX: SlangProgram = SlangProgram {
128 file: "probe_prefilter.slang",
129 entry: "probe_ggx",
130 label: "probe_ggx.slang",
131 gates: &["PROBE_GGX"],
132 sizes: Sizes::None,
133 msaa: false,
134};
135
136pub static GBUFFER_PREPASS_VERT: SlangProgram = SlangProgram {
142 file: "gbuffer_prepass.slang",
143 entry: "gbuffer_prepass_vertex",
144 label: "gbuffer_prepass_vert.slang",
145 gates: &["GB_STATIC"],
146 sizes: Sizes::None,
147 msaa: false,
148};
149pub static GBUFFER_PREPASS_VERT_INSTANCED: SlangProgram = SlangProgram {
151 file: "gbuffer_prepass.slang",
152 entry: "gbuffer_prepass_vertex_instanced",
153 label: "gbuffer_prepass_vert_instanced.slang",
154 gates: &["GB_INSTANCED"],
155 sizes: Sizes::None,
156 msaa: false,
157};
158pub static GBUFFER_PREPASS_VERT_SKINNED: SlangProgram = SlangProgram {
160 file: "gbuffer_prepass.slang",
161 entry: "gbuffer_prepass_vertex_skinned",
162 label: "gbuffer_prepass_vert_skinned.slang",
163 gates: &["GB_SKINNED"],
164 sizes: Sizes::None,
165 msaa: false,
166};
167pub static GBUFFER_BINDLESS_VERT: SlangProgram = SlangProgram {
169 file: "gbuffer_prepass.slang",
170 entry: "gbuffer_prepass_vertex_bindless",
171 label: "gbuffer_prepass_vert_bindless.slang",
172 gates: &["GB_BINDLESS"],
173 sizes: Sizes::None,
174 msaa: false,
175};
176pub static GBUFFER_PREPASS_FRAG: SlangProgram = SlangProgram {
178 file: "gbuffer_prepass.slang",
179 entry: "gbuffer_prepass_fragment",
180 label: "gbuffer_prepass_frag.slang",
181 gates: &["GB_FRAGMENT"],
182 sizes: Sizes::None,
183 msaa: false,
184};
185pub static GBUFFER_BINDLESS_FRAG: SlangProgram = SlangProgram {
187 file: "gbuffer_prepass.slang",
188 entry: "gbuffer_prepass_fragment_bindless",
189 label: "gbuffer_prepass_frag_bindless.slang",
190 gates: &["GB_FRAGMENT_BINDLESS"],
191 sizes: Sizes::None,
192 msaa: false,
193};
194pub static SHADOW_VERT: SlangProgram = SlangProgram {
196 file: "shadow.slang",
197 entry: "shadow_vertex_main",
198 label: "shadow_vert.slang",
199 gates: &["SHADOW_STATIC"],
200 sizes: Sizes::None,
201 msaa: false,
202};
203pub static SKINNED_SHADOW_VERT: SlangProgram = SlangProgram {
205 file: "shadow.slang",
206 entry: "shadow_vertex_main_skinned",
207 label: "shadow_vert_skinned.slang",
208 gates: &["SHADOW_SKINNED"],
209 sizes: Sizes::None,
210 msaa: false,
211};
212pub static SHADOW_BINDLESS_VERT: SlangProgram = SlangProgram {
214 file: "shadow.slang",
215 entry: "shadow_vertex_bindless",
216 label: "shadow_vert_bindless.slang",
217 gates: &["SHADOW_BINDLESS"],
218 sizes: Sizes::None,
219 msaa: false,
220};
221
222pub static FULLSCREEN_VERT: SlangProgram = SlangProgram {
226 file: "fullscreen.slang",
227 entry: "fullscreen_vertex",
228 label: "fullscreen_vert.slang",
229 gates: &[],
230 sizes: Sizes::None,
231 msaa: false,
232};
233pub static TAA_FRAG: SlangProgram = SlangProgram {
235 file: "taa.slang",
236 entry: "taa_fragment_main",
237 label: "taa_frag.slang",
238 gates: &[],
239 sizes: Sizes::None,
240 msaa: false,
241};
242pub static BLOOM_PREFILTER: SlangProgram = SlangProgram {
244 file: "bloom.slang",
245 entry: "bloom_prefilter_fragment",
246 label: "bloom_prefilter.slang",
247 gates: &["BLOOM_PREFILTER"],
248 sizes: Sizes::None,
249 msaa: false,
250};
251pub static BLOOM_DOWNSAMPLE: SlangProgram = SlangProgram {
253 file: "bloom.slang",
254 entry: "bloom_downsample_fragment",
255 label: "bloom_downsample.slang",
256 gates: &["BLOOM_DOWNSAMPLE"],
257 sizes: Sizes::None,
258 msaa: false,
259};
260pub static BLOOM_UPSAMPLE: SlangProgram = SlangProgram {
262 file: "bloom.slang",
263 entry: "bloom_upsample_fragment",
264 label: "bloom_upsample.slang",
265 gates: &["BLOOM_UPSAMPLE"],
266 sizes: Sizes::None,
267 msaa: false,
268};
269pub static COMPOSITE_FRAG: SlangProgram = SlangProgram {
271 file: "composite.slang",
272 entry: "composite_fragment",
273 label: "composite_frag.slang",
274 gates: &[],
275 sizes: Sizes::None,
276 msaa: false,
277};
278pub static SSAO_KERNEL: SlangProgram = SlangProgram {
280 file: "ssao.slang",
281 entry: "ssao_kernel_fragment",
282 label: "ssao_kernel.slang",
283 gates: &["SSAO_KERNEL"],
284 sizes: Sizes::None,
285 msaa: false,
286};
287pub static SSAO_BLUR: SlangProgram = SlangProgram {
289 file: "ssao.slang",
290 entry: "ssao_blur_fragment",
291 label: "ssao_blur.slang",
292 gates: &["SSAO_BLUR"],
293 sizes: Sizes::None,
294 msaa: false,
295};
296pub static SSR_RESOLVE: SlangProgram = SlangProgram {
298 file: "ssr.slang",
299 entry: "ssr_resolve_fragment",
300 label: "ssr_resolve.slang",
301 gates: &[],
302 sizes: Sizes::Probes,
303 msaa: false,
304};
305pub static SSGI_GATHER: SlangProgram = SlangProgram {
307 file: "ssgi.slang",
308 entry: "ssgi_gather_fragment",
309 label: "ssgi_gather.slang",
310 gates: &["SSGI_GATHER"],
311 sizes: Sizes::None,
312 msaa: false,
313};
314pub static SSGI_COMPOSITE: SlangProgram = SlangProgram {
316 file: "ssgi.slang",
317 entry: "ssgi_composite_fragment",
318 label: "ssgi_composite.slang",
319 gates: &["SSGI_COMPOSITE"],
320 sizes: Sizes::None,
321 msaa: false,
322};
323pub static REFLECTION_BLUR: SlangProgram = SlangProgram {
325 file: "reflection.slang",
326 entry: "reflection_blur_fragment",
327 label: "reflection_blur.slang",
328 gates: &["REFLECTION_BLUR"],
329 sizes: Sizes::None,
330 msaa: false,
331};
332pub static REFLECTION_COMPOSITE: SlangProgram = SlangProgram {
334 file: "reflection.slang",
335 entry: "reflection_composite_fragment",
336 label: "reflection_composite.slang",
337 gates: &["REFLECTION_COMPOSITE"],
338 sizes: Sizes::None,
339 msaa: false,
340};
341
342pub static FOG_FROXEL: SlangProgram = SlangProgram {
346 file: "fog.slang",
347 entry: "fog_froxel_kernel",
348 label: "fog_froxel.slang",
349 gates: &["FOG_FROXEL"],
350 sizes: Sizes::None,
351 msaa: false,
352};
353pub static FOG_FRAG: SlangProgram = SlangProgram {
355 file: "fog.slang",
356 entry: "fog_fragment",
357 label: "fog_frag.slang",
358 gates: &[],
359 sizes: Sizes::None,
360 msaa: true,
361};
362pub static AUTO_EXPOSURE_BUILD: SlangProgram = SlangProgram {
364 file: "auto_exposure.slang",
365 entry: "histogram_build",
366 label: "auto_exposure_build.slang",
367 gates: &["AE_BUILD"],
368 sizes: Sizes::None,
369 msaa: false,
370};
371pub static AUTO_EXPOSURE_AVERAGE: SlangProgram = SlangProgram {
373 file: "auto_exposure.slang",
374 entry: "histogram_average",
375 label: "auto_exposure_average.slang",
376 gates: &["AE_AVERAGE"],
377 sizes: Sizes::None,
378 msaa: false,
379};
380pub static RT_SKIN: SlangProgram = SlangProgram {
382 file: "rt_skin.slang",
383 entry: "rt_skin",
384 label: "rt_skin.slang",
385 gates: &[],
386 sizes: Sizes::None,
387 msaa: false,
388};
389pub static PARTICLE_SIMULATE: SlangProgram = SlangProgram {
391 file: "particle_simulate.slang",
392 entry: "particle_simulate",
393 label: "particle_simulate.slang",
394 gates: &[],
395 sizes: Sizes::None,
396 msaa: false,
397};
398
399pub static PARTICLE_VERT: SlangProgram = SlangProgram {
406 file: "particle.slang",
407 entry: "particle_vertex",
408 label: "particle_vert.slang",
409 gates: &[],
410 sizes: Sizes::None,
411 msaa: false,
412};
413pub static PARTICLE_FRAG: SlangProgram = SlangProgram {
415 file: "particle.slang",
416 entry: "particle_fragment",
417 label: "particle_frag.slang",
418 gates: &[],
419 sizes: Sizes::None,
420 msaa: false,
421};
422pub static DECAL_VERT: SlangProgram = SlangProgram {
424 file: "decal.slang",
425 entry: "decal_vertex",
426 label: "decal_vert.slang",
427 gates: &[],
428 sizes: Sizes::None,
429 msaa: false,
430};
431pub static DECAL_FRAG: SlangProgram = SlangProgram {
433 file: "decal.slang",
434 entry: "decal_fragment",
435 label: "decal_frag.slang",
436 gates: &[],
437 sizes: Sizes::None,
438 msaa: true,
439};
440pub static LINE_VERT: SlangProgram = SlangProgram {
442 file: "line.slang",
443 entry: "line_vertex",
444 label: "line_vert.slang",
445 gates: &[],
446 sizes: Sizes::None,
447 msaa: false,
448};
449pub static LINE_FRAG: SlangProgram = SlangProgram {
451 file: "line.slang",
452 entry: "line_fragment",
453 label: "line_frag.slang",
454 gates: &[],
455 sizes: Sizes::None,
456 msaa: true,
457};
458pub static TEXT_VERT: SlangProgram = SlangProgram {
460 file: "text.slang",
461 entry: "text_vertex_main",
462 label: "text_vert.slang",
463 gates: &[],
464 sizes: Sizes::None,
465 msaa: false,
466};
467pub static TEXT_FRAG: SlangProgram = SlangProgram {
469 file: "text.slang",
470 entry: "text_fragment_main",
471 label: "text_frag.slang",
472 gates: &[],
473 sizes: Sizes::None,
474 msaa: false,
475};
476
477pub static RT_REFLECTIONS_FRAG: SlangProgram = SlangProgram {
485 file: "rt_reflections.slang",
486 entry: "rt_reflections_fragment",
487 label: "rt_reflections.slang",
488 gates: &[],
489 sizes: Sizes::Probes,
490 msaa: false,
491};
492pub static RT_REFLECTIONS_FRAG_TEXTURED: SlangProgram = SlangProgram {
494 file: "rt_reflections.slang",
495 entry: "rt_reflections_fragment",
496 label: "rt_reflections_textured.slang",
497 gates: &["RT_TEXTURED"],
498 sizes: Sizes::PoolAndProbes,
499 msaa: false,
500};
501pub static GLASS_VERT: SlangProgram = SlangProgram {
503 file: "glass.slang",
504 entry: "glass_vertex",
505 label: "glass_vert.slang",
506 gates: &[],
507 sizes: Sizes::Probes,
508 msaa: true,
509};
510pub static GLASS_FRAG: SlangProgram = SlangProgram {
512 file: "glass.slang",
513 entry: "glass_fragment",
514 label: "glass_frag.slang",
515 gates: &[],
516 sizes: Sizes::Probes,
517 msaa: true,
518};
519pub static GLASS_FRAG_RT: SlangProgram = SlangProgram {
521 file: "glass.slang",
522 entry: "glass_rt_fragment",
523 label: "glass_frag_rt.slang",
524 gates: &["GLASS_RT"],
525 sizes: Sizes::Probes,
526 msaa: true,
527};
528pub static GLASS_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
530 file: "glass.slang",
531 entry: "glass_rt_fragment",
532 label: "glass_frag_rt_textured.slang",
533 gates: &["GLASS_RT", "RT_TEXTURED"],
534 sizes: Sizes::PoolAndProbes,
535 msaa: true,
536};
537
538pub static GLASS_MESH_VERT: SlangProgram = SlangProgram {
545 file: "glass_mesh.slang",
546 entry: "glass_mesh_vertex",
547 label: "glass_mesh_vert.slang",
548 gates: &[],
549 sizes: Sizes::Probes,
550 msaa: true,
551};
552pub static GLASS_MESH_FRAG_RT: SlangProgram = SlangProgram {
554 file: "glass_mesh.slang",
555 entry: "glass_mesh_rt_fragment",
556 label: "glass_mesh_frag_rt.slang",
557 gates: &[],
558 sizes: Sizes::Probes,
559 msaa: true,
560};
561pub static GLASS_MESH_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
563 file: "glass_mesh.slang",
564 entry: "glass_mesh_rt_fragment",
565 label: "glass_mesh_frag_rt_textured.slang",
566 gates: &["RT_TEXTURED"],
567 sizes: Sizes::PoolAndProbes,
568 msaa: true,
569};
570
571pub static WATER_VERT: SlangProgram = SlangProgram {
577 file: "water.slang",
578 entry: "water_vertex",
579 label: "water_vert.slang",
580 gates: &[],
581 sizes: Sizes::Probes,
582 msaa: true,
583};
584pub static WATER_FRAG: SlangProgram = SlangProgram {
586 file: "water.slang",
587 entry: "water_fragment",
588 label: "water_frag.slang",
589 gates: &[],
590 sizes: Sizes::Probes,
591 msaa: true,
592};
593pub static WATER_FRAG_RT: SlangProgram = SlangProgram {
595 file: "water.slang",
596 entry: "water_rt_fragment",
597 label: "water_frag_rt.slang",
598 gates: &["WATER_RT"],
599 sizes: Sizes::Probes,
600 msaa: true,
601};
602pub static WATER_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
604 file: "water.slang",
605 entry: "water_rt_fragment",
606 label: "water_frag_rt_textured.slang",
607 gates: &["WATER_RT", "RT_TEXTURED"],
608 sizes: Sizes::PoolAndProbes,
609 msaa: true,
610};
611
612pub static ALL: &[&SlangProgram] = &[
616 &MAIN_BINDLESS_VERT,
617 &MAIN_BINDLESS_FRAG,
618 &LIGHT_CULL,
619 &RT_SKIN,
620 &HIZ_INIT_MSAA,
621 &HIZ_INIT_SINGLE,
622 &HIZ_DOWNSAMPLE,
623 &PROBE_MIP0,
624 &PROBE_DOWNSAMPLE,
625 &PROBE_GGX,
626 &GBUFFER_PREPASS_VERT,
627 &GBUFFER_PREPASS_VERT_INSTANCED,
628 &GBUFFER_PREPASS_VERT_SKINNED,
629 &GBUFFER_BINDLESS_VERT,
630 &GBUFFER_PREPASS_FRAG,
631 &GBUFFER_BINDLESS_FRAG,
632 &SHADOW_VERT,
633 &SKINNED_SHADOW_VERT,
634 &SHADOW_BINDLESS_VERT,
635 &FULLSCREEN_VERT,
636 &TAA_FRAG,
637 &BLOOM_PREFILTER,
638 &BLOOM_DOWNSAMPLE,
639 &BLOOM_UPSAMPLE,
640 &COMPOSITE_FRAG,
641 &SSAO_KERNEL,
642 &SSAO_BLUR,
643 &SSR_RESOLVE,
644 &SSGI_GATHER,
645 &SSGI_COMPOSITE,
646 &REFLECTION_BLUR,
647 &REFLECTION_COMPOSITE,
648 &FOG_FROXEL,
649 &FOG_FRAG,
650 &AUTO_EXPOSURE_BUILD,
651 &AUTO_EXPOSURE_AVERAGE,
652 &PARTICLE_SIMULATE,
653 &PARTICLE_VERT,
654 &PARTICLE_FRAG,
655 &DECAL_VERT,
656 &DECAL_FRAG,
657 &LINE_VERT,
658 &LINE_FRAG,
659 &TEXT_VERT,
660 &TEXT_FRAG,
661 &RT_REFLECTIONS_FRAG,
662 &RT_REFLECTIONS_FRAG_TEXTURED,
663 &GLASS_VERT,
664 &GLASS_FRAG,
665 &GLASS_FRAG_RT,
666 &GLASS_FRAG_RT_TEXTURED,
667 &GLASS_MESH_VERT,
668 &GLASS_MESH_FRAG_RT,
669 &GLASS_MESH_FRAG_RT_TEXTURED,
670 &WATER_VERT,
671 &WATER_FRAG,
672 &WATER_FRAG_RT,
673 &WATER_FRAG_RT_TEXTURED,
674];
675
676#[cfg(test)]
677mod tests {
678 use super::*;
679 use alloc::vec::Vec;
680
681 #[test]
685 fn every_program_has_a_distinct_label() {
686 let mut labels: Vec<&str> = ALL.iter().map(|p| p.label).collect();
687 let declared = labels.len();
688 labels.sort_unstable();
689 labels.dedup();
690 assert_eq!(
691 labels.len(),
692 declared,
693 "two programs share a label, so they would share a precompiled artifact"
694 );
695 }
696
697 #[test]
698 fn every_program_names_an_embedded_shader() {
699 for p in ALL {
700 assert!(
701 crate::render::shaders::embedded(p.file).is_some(),
702 "{}: no embedded {}",
703 p.label,
704 p.file
705 );
706 }
707 }
708
709 #[test]
713 fn the_only_per_host_variant_is_the_sample_count() {
714 let sampled = ALL.iter().filter(|p| p.msaa).count();
715 assert!(sampled > 0, "the MSAA dimension went missing");
716 assert!(sampled < ALL.len(), "every program cannot read the depth");
717 for p in ALL {
718 assert!(!p.entry.is_empty(), "{}", p.label);
719 }
720 }
721}