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 GBUFFER_PREPASS_VERT: SlangProgram = SlangProgram {
114 file: "gbuffer_prepass.slang",
115 entry: "gbuffer_prepass_vertex",
116 label: "gbuffer_prepass_vert.slang",
117 gates: &["GB_STATIC"],
118 sizes: Sizes::None,
119 msaa: false,
120};
121pub static GBUFFER_PREPASS_VERT_INSTANCED: SlangProgram = SlangProgram {
123 file: "gbuffer_prepass.slang",
124 entry: "gbuffer_prepass_vertex_instanced",
125 label: "gbuffer_prepass_vert_instanced.slang",
126 gates: &["GB_INSTANCED"],
127 sizes: Sizes::None,
128 msaa: false,
129};
130pub static GBUFFER_PREPASS_VERT_SKINNED: SlangProgram = SlangProgram {
132 file: "gbuffer_prepass.slang",
133 entry: "gbuffer_prepass_vertex_skinned",
134 label: "gbuffer_prepass_vert_skinned.slang",
135 gates: &["GB_SKINNED"],
136 sizes: Sizes::None,
137 msaa: false,
138};
139pub static GBUFFER_BINDLESS_VERT: SlangProgram = SlangProgram {
141 file: "gbuffer_prepass.slang",
142 entry: "gbuffer_prepass_vertex_bindless",
143 label: "gbuffer_prepass_vert_bindless.slang",
144 gates: &["GB_BINDLESS"],
145 sizes: Sizes::None,
146 msaa: false,
147};
148pub static GBUFFER_PREPASS_FRAG: SlangProgram = SlangProgram {
150 file: "gbuffer_prepass.slang",
151 entry: "gbuffer_prepass_fragment",
152 label: "gbuffer_prepass_frag.slang",
153 gates: &["GB_FRAGMENT"],
154 sizes: Sizes::None,
155 msaa: false,
156};
157pub static GBUFFER_BINDLESS_FRAG: SlangProgram = SlangProgram {
159 file: "gbuffer_prepass.slang",
160 entry: "gbuffer_prepass_fragment_bindless",
161 label: "gbuffer_prepass_frag_bindless.slang",
162 gates: &["GB_FRAGMENT_BINDLESS"],
163 sizes: Sizes::None,
164 msaa: false,
165};
166pub static SHADOW_VERT: SlangProgram = SlangProgram {
168 file: "shadow.slang",
169 entry: "shadow_vertex_main",
170 label: "shadow_vert.slang",
171 gates: &["SHADOW_STATIC"],
172 sizes: Sizes::None,
173 msaa: false,
174};
175pub static SKINNED_SHADOW_VERT: SlangProgram = SlangProgram {
177 file: "shadow.slang",
178 entry: "shadow_vertex_main_skinned",
179 label: "shadow_vert_skinned.slang",
180 gates: &["SHADOW_SKINNED"],
181 sizes: Sizes::None,
182 msaa: false,
183};
184pub static SHADOW_BINDLESS_VERT: SlangProgram = SlangProgram {
186 file: "shadow.slang",
187 entry: "shadow_vertex_bindless",
188 label: "shadow_vert_bindless.slang",
189 gates: &["SHADOW_BINDLESS"],
190 sizes: Sizes::None,
191 msaa: false,
192};
193
194pub static FULLSCREEN_VERT: SlangProgram = SlangProgram {
198 file: "fullscreen.slang",
199 entry: "fullscreen_vertex",
200 label: "fullscreen_vert.slang",
201 gates: &[],
202 sizes: Sizes::None,
203 msaa: false,
204};
205pub static TAA_FRAG: SlangProgram = SlangProgram {
207 file: "taa.slang",
208 entry: "taa_fragment_main",
209 label: "taa_frag.slang",
210 gates: &[],
211 sizes: Sizes::None,
212 msaa: false,
213};
214pub static BLOOM_PREFILTER: SlangProgram = SlangProgram {
216 file: "bloom.slang",
217 entry: "bloom_prefilter_fragment",
218 label: "bloom_prefilter.slang",
219 gates: &["BLOOM_PREFILTER"],
220 sizes: Sizes::None,
221 msaa: false,
222};
223pub static BLOOM_DOWNSAMPLE: SlangProgram = SlangProgram {
225 file: "bloom.slang",
226 entry: "bloom_downsample_fragment",
227 label: "bloom_downsample.slang",
228 gates: &["BLOOM_DOWNSAMPLE"],
229 sizes: Sizes::None,
230 msaa: false,
231};
232pub static BLOOM_UPSAMPLE: SlangProgram = SlangProgram {
234 file: "bloom.slang",
235 entry: "bloom_upsample_fragment",
236 label: "bloom_upsample.slang",
237 gates: &["BLOOM_UPSAMPLE"],
238 sizes: Sizes::None,
239 msaa: false,
240};
241pub static COMPOSITE_FRAG: SlangProgram = SlangProgram {
243 file: "composite.slang",
244 entry: "composite_fragment",
245 label: "composite_frag.slang",
246 gates: &[],
247 sizes: Sizes::None,
248 msaa: false,
249};
250pub static SSAO_KERNEL: SlangProgram = SlangProgram {
252 file: "ssao.slang",
253 entry: "ssao_kernel_fragment",
254 label: "ssao_kernel.slang",
255 gates: &["SSAO_KERNEL"],
256 sizes: Sizes::None,
257 msaa: false,
258};
259pub static SSAO_BLUR: SlangProgram = SlangProgram {
261 file: "ssao.slang",
262 entry: "ssao_blur_fragment",
263 label: "ssao_blur.slang",
264 gates: &["SSAO_BLUR"],
265 sizes: Sizes::None,
266 msaa: false,
267};
268pub static SSR_RESOLVE: SlangProgram = SlangProgram {
270 file: "ssr.slang",
271 entry: "ssr_resolve_fragment",
272 label: "ssr_resolve.slang",
273 gates: &[],
274 sizes: Sizes::Probes,
275 msaa: false,
276};
277pub static SSGI_GATHER: SlangProgram = SlangProgram {
279 file: "ssgi.slang",
280 entry: "ssgi_gather_fragment",
281 label: "ssgi_gather.slang",
282 gates: &["SSGI_GATHER"],
283 sizes: Sizes::None,
284 msaa: false,
285};
286pub static SSGI_COMPOSITE: SlangProgram = SlangProgram {
288 file: "ssgi.slang",
289 entry: "ssgi_composite_fragment",
290 label: "ssgi_composite.slang",
291 gates: &["SSGI_COMPOSITE"],
292 sizes: Sizes::None,
293 msaa: false,
294};
295pub static REFLECTION_BLUR: SlangProgram = SlangProgram {
297 file: "reflection.slang",
298 entry: "reflection_blur_fragment",
299 label: "reflection_blur.slang",
300 gates: &["REFLECTION_BLUR"],
301 sizes: Sizes::None,
302 msaa: false,
303};
304pub static REFLECTION_COMPOSITE: SlangProgram = SlangProgram {
306 file: "reflection.slang",
307 entry: "reflection_composite_fragment",
308 label: "reflection_composite.slang",
309 gates: &["REFLECTION_COMPOSITE"],
310 sizes: Sizes::None,
311 msaa: false,
312};
313
314pub static FOG_FROXEL: SlangProgram = SlangProgram {
318 file: "fog.slang",
319 entry: "fog_froxel_kernel",
320 label: "fog_froxel.slang",
321 gates: &["FOG_FROXEL"],
322 sizes: Sizes::None,
323 msaa: false,
324};
325pub static FOG_FRAG: SlangProgram = SlangProgram {
327 file: "fog.slang",
328 entry: "fog_fragment",
329 label: "fog_frag.slang",
330 gates: &[],
331 sizes: Sizes::None,
332 msaa: true,
333};
334pub static AUTO_EXPOSURE_BUILD: SlangProgram = SlangProgram {
336 file: "auto_exposure.slang",
337 entry: "histogram_build",
338 label: "auto_exposure_build.slang",
339 gates: &["AE_BUILD"],
340 sizes: Sizes::None,
341 msaa: false,
342};
343pub static AUTO_EXPOSURE_AVERAGE: SlangProgram = SlangProgram {
345 file: "auto_exposure.slang",
346 entry: "histogram_average",
347 label: "auto_exposure_average.slang",
348 gates: &["AE_AVERAGE"],
349 sizes: Sizes::None,
350 msaa: false,
351};
352pub static RT_SKIN: SlangProgram = SlangProgram {
354 file: "rt_skin.slang",
355 entry: "rt_skin",
356 label: "rt_skin.slang",
357 gates: &[],
358 sizes: Sizes::None,
359 msaa: false,
360};
361pub static PARTICLE_SIMULATE: SlangProgram = SlangProgram {
363 file: "particle_simulate.slang",
364 entry: "particle_simulate",
365 label: "particle_simulate.slang",
366 gates: &[],
367 sizes: Sizes::None,
368 msaa: false,
369};
370
371pub static PARTICLE_VERT: SlangProgram = SlangProgram {
378 file: "particle.slang",
379 entry: "particle_vertex",
380 label: "particle_vert.slang",
381 gates: &[],
382 sizes: Sizes::None,
383 msaa: false,
384};
385pub static PARTICLE_FRAG: SlangProgram = SlangProgram {
387 file: "particle.slang",
388 entry: "particle_fragment",
389 label: "particle_frag.slang",
390 gates: &[],
391 sizes: Sizes::None,
392 msaa: false,
393};
394pub static DECAL_VERT: SlangProgram = SlangProgram {
396 file: "decal.slang",
397 entry: "decal_vertex",
398 label: "decal_vert.slang",
399 gates: &[],
400 sizes: Sizes::None,
401 msaa: false,
402};
403pub static DECAL_FRAG: SlangProgram = SlangProgram {
405 file: "decal.slang",
406 entry: "decal_fragment",
407 label: "decal_frag.slang",
408 gates: &[],
409 sizes: Sizes::None,
410 msaa: true,
411};
412pub static LINE_VERT: SlangProgram = SlangProgram {
414 file: "line.slang",
415 entry: "line_vertex",
416 label: "line_vert.slang",
417 gates: &[],
418 sizes: Sizes::None,
419 msaa: false,
420};
421pub static LINE_FRAG: SlangProgram = SlangProgram {
423 file: "line.slang",
424 entry: "line_fragment",
425 label: "line_frag.slang",
426 gates: &[],
427 sizes: Sizes::None,
428 msaa: true,
429};
430pub static TEXT_VERT: SlangProgram = SlangProgram {
432 file: "text.slang",
433 entry: "text_vertex_main",
434 label: "text_vert.slang",
435 gates: &[],
436 sizes: Sizes::None,
437 msaa: false,
438};
439pub static TEXT_FRAG: SlangProgram = SlangProgram {
441 file: "text.slang",
442 entry: "text_fragment_main",
443 label: "text_frag.slang",
444 gates: &[],
445 sizes: Sizes::None,
446 msaa: false,
447};
448
449pub static RT_REFLECTIONS_FRAG: SlangProgram = SlangProgram {
457 file: "rt_reflections.slang",
458 entry: "rt_reflections_fragment",
459 label: "rt_reflections.slang",
460 gates: &[],
461 sizes: Sizes::Probes,
462 msaa: false,
463};
464pub static RT_REFLECTIONS_FRAG_TEXTURED: SlangProgram = SlangProgram {
466 file: "rt_reflections.slang",
467 entry: "rt_reflections_fragment",
468 label: "rt_reflections_textured.slang",
469 gates: &["RT_TEXTURED"],
470 sizes: Sizes::PoolAndProbes,
471 msaa: false,
472};
473pub static GLASS_VERT: SlangProgram = SlangProgram {
475 file: "glass.slang",
476 entry: "glass_vertex",
477 label: "glass_vert.slang",
478 gates: &[],
479 sizes: Sizes::Probes,
480 msaa: true,
481};
482pub static GLASS_FRAG: SlangProgram = SlangProgram {
484 file: "glass.slang",
485 entry: "glass_fragment",
486 label: "glass_frag.slang",
487 gates: &[],
488 sizes: Sizes::Probes,
489 msaa: true,
490};
491pub static GLASS_FRAG_RT: SlangProgram = SlangProgram {
493 file: "glass.slang",
494 entry: "glass_rt_fragment",
495 label: "glass_frag_rt.slang",
496 gates: &["GLASS_RT"],
497 sizes: Sizes::Probes,
498 msaa: true,
499};
500pub static GLASS_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
502 file: "glass.slang",
503 entry: "glass_rt_fragment",
504 label: "glass_frag_rt_textured.slang",
505 gates: &["GLASS_RT", "RT_TEXTURED"],
506 sizes: Sizes::PoolAndProbes,
507 msaa: true,
508};
509
510pub static GLASS_MESH_VERT: SlangProgram = SlangProgram {
517 file: "glass_mesh.slang",
518 entry: "glass_mesh_vertex",
519 label: "glass_mesh_vert.slang",
520 gates: &[],
521 sizes: Sizes::Probes,
522 msaa: true,
523};
524pub static GLASS_MESH_FRAG_RT: SlangProgram = SlangProgram {
526 file: "glass_mesh.slang",
527 entry: "glass_mesh_rt_fragment",
528 label: "glass_mesh_frag_rt.slang",
529 gates: &[],
530 sizes: Sizes::Probes,
531 msaa: true,
532};
533pub static GLASS_MESH_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
535 file: "glass_mesh.slang",
536 entry: "glass_mesh_rt_fragment",
537 label: "glass_mesh_frag_rt_textured.slang",
538 gates: &["RT_TEXTURED"],
539 sizes: Sizes::PoolAndProbes,
540 msaa: true,
541};
542
543pub static WATER_VERT: SlangProgram = SlangProgram {
549 file: "water.slang",
550 entry: "water_vertex",
551 label: "water_vert.slang",
552 gates: &[],
553 sizes: Sizes::Probes,
554 msaa: true,
555};
556pub static WATER_FRAG: SlangProgram = SlangProgram {
558 file: "water.slang",
559 entry: "water_fragment",
560 label: "water_frag.slang",
561 gates: &[],
562 sizes: Sizes::Probes,
563 msaa: true,
564};
565pub static WATER_FRAG_RT: SlangProgram = SlangProgram {
567 file: "water.slang",
568 entry: "water_rt_fragment",
569 label: "water_frag_rt.slang",
570 gates: &["WATER_RT"],
571 sizes: Sizes::Probes,
572 msaa: true,
573};
574pub static WATER_FRAG_RT_TEXTURED: SlangProgram = SlangProgram {
576 file: "water.slang",
577 entry: "water_rt_fragment",
578 label: "water_frag_rt_textured.slang",
579 gates: &["WATER_RT", "RT_TEXTURED"],
580 sizes: Sizes::PoolAndProbes,
581 msaa: true,
582};
583
584pub static ALL: &[&SlangProgram] = &[
588 &MAIN_BINDLESS_VERT,
589 &MAIN_BINDLESS_FRAG,
590 &LIGHT_CULL,
591 &RT_SKIN,
592 &HIZ_INIT_MSAA,
593 &HIZ_INIT_SINGLE,
594 &HIZ_DOWNSAMPLE,
595 &GBUFFER_PREPASS_VERT,
596 &GBUFFER_PREPASS_VERT_INSTANCED,
597 &GBUFFER_PREPASS_VERT_SKINNED,
598 &GBUFFER_BINDLESS_VERT,
599 &GBUFFER_PREPASS_FRAG,
600 &GBUFFER_BINDLESS_FRAG,
601 &SHADOW_VERT,
602 &SKINNED_SHADOW_VERT,
603 &SHADOW_BINDLESS_VERT,
604 &FULLSCREEN_VERT,
605 &TAA_FRAG,
606 &BLOOM_PREFILTER,
607 &BLOOM_DOWNSAMPLE,
608 &BLOOM_UPSAMPLE,
609 &COMPOSITE_FRAG,
610 &SSAO_KERNEL,
611 &SSAO_BLUR,
612 &SSR_RESOLVE,
613 &SSGI_GATHER,
614 &SSGI_COMPOSITE,
615 &REFLECTION_BLUR,
616 &REFLECTION_COMPOSITE,
617 &FOG_FROXEL,
618 &FOG_FRAG,
619 &AUTO_EXPOSURE_BUILD,
620 &AUTO_EXPOSURE_AVERAGE,
621 &PARTICLE_SIMULATE,
622 &PARTICLE_VERT,
623 &PARTICLE_FRAG,
624 &DECAL_VERT,
625 &DECAL_FRAG,
626 &LINE_VERT,
627 &LINE_FRAG,
628 &TEXT_VERT,
629 &TEXT_FRAG,
630 &RT_REFLECTIONS_FRAG,
631 &RT_REFLECTIONS_FRAG_TEXTURED,
632 &GLASS_VERT,
633 &GLASS_FRAG,
634 &GLASS_FRAG_RT,
635 &GLASS_FRAG_RT_TEXTURED,
636 &GLASS_MESH_VERT,
637 &GLASS_MESH_FRAG_RT,
638 &GLASS_MESH_FRAG_RT_TEXTURED,
639 &WATER_VERT,
640 &WATER_FRAG,
641 &WATER_FRAG_RT,
642 &WATER_FRAG_RT_TEXTURED,
643];
644
645#[cfg(test)]
646mod tests {
647 use super::*;
648 use alloc::vec::Vec;
649
650 #[test]
654 fn every_program_has_a_distinct_label() {
655 let mut labels: Vec<&str> = ALL.iter().map(|p| p.label).collect();
656 let declared = labels.len();
657 labels.sort_unstable();
658 labels.dedup();
659 assert_eq!(
660 labels.len(),
661 declared,
662 "two programs share a label, so they would share a precompiled artifact"
663 );
664 }
665
666 #[test]
667 fn every_program_names_an_embedded_shader() {
668 for p in ALL {
669 assert!(
670 crate::render::shaders::embedded(p.file).is_some(),
671 "{}: no embedded {}",
672 p.label,
673 p.file
674 );
675 }
676 }
677
678 #[test]
682 fn the_only_per_host_variant_is_the_sample_count() {
683 let sampled = ALL.iter().filter(|p| p.msaa).count();
684 assert!(sampled > 0, "the MSAA dimension went missing");
685 assert!(sampled < ALL.len(), "every program cannot read the depth");
686 for p in ALL {
687 assert!(!p.entry.is_empty(), "{}", p.label);
688 }
689 }
690}