rafx_framework/render_features/
macro_render_phase.rs

1// Use to declare a new render phase that can be registered. Registration allows easy global
2// access to the render phase index from anywhere in the binary
3//
4// Use like this:
5//      rafx::declare_render_phase!(Debug3DRenderFeature, DEBUG_3D_RENDER_FEATURE, sort_fn);
6//
7// The first name is all that really matters, the second name just needs to be a constant that is
8// exposed via the first name (i.e. Debug3DRenderFeature::feature_index())
9//
10// The function provided is a sort function like this:
11//
12// fn sort_submit_nodes(mut submit_nodes: Vec<SubmitNode>) -> Vec<SubmitNode> {
13//     // Sort by feature
14//     log::trace!("Sort phase {}", MyRenderPhase::render_phase_debug_name());
15//     submit_nodes.sort_unstable_by(|a, b| a.feature_index().cmp(&b.feature_index()));
16//
17//     submit_nodes
18// }
19//
20// This can be use to implement back to front and front to back sorting, or just sort by feature
21// if order doesn't matter to get the best batching
22#[macro_export]
23macro_rules! declare_render_phase {
24    ($struct_name:ident, $atomic_constant_name:ident, $sort_fn:ident) => {
25        static $atomic_constant_name: std::sync::atomic::AtomicI32 =
26            std::sync::atomic::AtomicI32::new(-1);
27
28        pub struct $struct_name;
29
30        impl $crate::render_features::RenderPhase for $struct_name {
31            fn set_render_phase_index(index: $crate::render_features::RenderPhaseIndex) {
32                assert_eq!(
33                    $struct_name::render_phase_index(),
34                    $crate::render_features::RenderPhaseIndex::MAX,
35                    "render phase {} was already registered",
36                    $struct_name::render_phase_debug_name(),
37                );
38
39                use std::convert::TryInto;
40                $atomic_constant_name.store(
41                    index.try_into().unwrap(),
42                    std::sync::atomic::Ordering::Release,
43                );
44            }
45
46            fn render_phase_index() -> $crate::render_features::RenderPhaseIndex {
47                $atomic_constant_name.load(std::sync::atomic::Ordering::Acquire)
48                    as $crate::render_features::RenderPhaseIndex
49            }
50
51            fn sort_submit_nodes(
52                submit_nodes: &mut Vec<$crate::render_features::RenderFeatureSubmitNode>
53            ) {
54                $sort_fn(submit_nodes)
55            }
56
57            fn render_phase_debug_name() -> &'static str {
58                stringify!($struct_name)
59            }
60        }
61    };
62}