oxihuman_viewer/
render_graph.rs1#![allow(dead_code)]
4
5use std::collections::HashMap;
8
9#[allow(dead_code)]
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub enum PassKind {
13 Render,
14 Compute,
15 Transfer,
16}
17
18#[allow(dead_code)]
20#[derive(Clone, Debug)]
21pub struct RgNode {
22 pub id: u32,
23 pub name: String,
24 pub kind: PassKind,
25 pub enabled: bool,
26}
27
28#[allow(dead_code)]
30#[derive(Clone, Debug, Default)]
31pub struct RenderGraph {
32 pub nodes: Vec<RgNode>,
33 pub deps: HashMap<u32, Vec<u32>>,
35 pub next_id: u32,
36}
37
38#[allow(dead_code)]
39pub fn new_render_graph() -> RenderGraph {
40 RenderGraph::default()
41}
42
43#[allow(dead_code)]
44pub fn rg_add_node(graph: &mut RenderGraph, name: &str, kind: PassKind) -> u32 {
45 let id = graph.next_id;
46 graph.next_id += 1;
47 graph.nodes.push(RgNode {
48 id,
49 name: name.to_string(),
50 kind,
51 enabled: true,
52 });
53 id
54}
55
56#[allow(dead_code)]
57pub fn rg_add_dep(graph: &mut RenderGraph, node: u32, dep: u32) {
58 graph.deps.entry(node).or_default().push(dep);
59}
60
61#[allow(dead_code)]
62pub fn rg_set_enabled(graph: &mut RenderGraph, id: u32, v: bool) {
63 if let Some(n) = graph.nodes.iter_mut().find(|n| n.id == id) {
64 n.enabled = v;
65 }
66}
67
68#[allow(dead_code)]
69pub fn rg_node_count(graph: &RenderGraph) -> usize {
70 graph.nodes.len()
71}
72
73#[allow(dead_code)]
74pub fn rg_enabled_count(graph: &RenderGraph) -> usize {
75 graph.nodes.iter().filter(|n| n.enabled).count()
76}
77
78#[allow(dead_code)]
79pub fn rg_dep_count(graph: &RenderGraph, node: u32) -> usize {
80 graph.deps.get(&node).map(|v| v.len()).unwrap_or(0)
81}
82
83#[allow(dead_code)]
84pub fn rg_pass_name(kind: PassKind) -> &'static str {
85 match kind {
86 PassKind::Render => "render",
87 PassKind::Compute => "compute",
88 PassKind::Transfer => "transfer",
89 }
90}
91
92#[allow(dead_code)]
93pub fn rg_clear(graph: &mut RenderGraph) {
94 graph.nodes.clear();
95 graph.deps.clear();
96}
97
98#[allow(dead_code)]
99pub fn rg_to_json(graph: &RenderGraph) -> String {
100 let nodes: Vec<String> = graph
101 .nodes
102 .iter()
103 .map(|n| {
104 format!(
105 "{{\"id\":{},\"name\":\"{}\",\"kind\":\"{}\",\"enabled\":{}}}",
106 n.id,
107 n.name,
108 rg_pass_name(n.kind),
109 n.enabled
110 )
111 })
112 .collect();
113 format!("{{\"nodes\":[{}]}}", nodes.join(","))
114}
115
116#[allow(dead_code)]
118pub fn rg_topo_sort(graph: &RenderGraph) -> Vec<u32> {
119 let mut order: Vec<u32> = graph.nodes.iter().map(|n| n.id).collect();
120 order.sort();
121 order
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
129 fn new_empty() {
130 assert_eq!(rg_node_count(&new_render_graph()), 0);
131 }
132
133 #[test]
134 fn add_node() {
135 let mut g = new_render_graph();
136 rg_add_node(&mut g, "shadows", PassKind::Render);
137 assert_eq!(rg_node_count(&g), 1);
138 }
139
140 #[test]
141 fn ids_increment() {
142 let mut g = new_render_graph();
143 let a = rg_add_node(&mut g, "a", PassKind::Render);
144 let b = rg_add_node(&mut g, "b", PassKind::Compute);
145 assert_ne!(a, b);
146 }
147
148 #[test]
149 fn add_dep() {
150 let mut g = new_render_graph();
151 let a = rg_add_node(&mut g, "a", PassKind::Render);
152 let b = rg_add_node(&mut g, "b", PassKind::Render);
153 rg_add_dep(&mut g, b, a);
154 assert_eq!(rg_dep_count(&g, b), 1);
155 }
156
157 #[test]
158 fn set_disabled() {
159 let mut g = new_render_graph();
160 let id = rg_add_node(&mut g, "x", PassKind::Transfer);
161 rg_set_enabled(&mut g, id, false);
162 assert_eq!(rg_enabled_count(&g), 0);
163 }
164
165 #[test]
166 fn all_enabled_by_default() {
167 let mut g = new_render_graph();
168 rg_add_node(&mut g, "a", PassKind::Render);
169 rg_add_node(&mut g, "b", PassKind::Render);
170 assert_eq!(rg_enabled_count(&g), 2);
171 }
172
173 #[test]
174 fn pass_name() {
175 assert_eq!(rg_pass_name(PassKind::Compute), "compute");
176 }
177
178 #[test]
179 fn clear() {
180 let mut g = new_render_graph();
181 rg_add_node(&mut g, "x", PassKind::Render);
182 rg_clear(&mut g);
183 assert_eq!(rg_node_count(&g), 0);
184 }
185
186 #[test]
187 fn topo_sort_len() {
188 let mut g = new_render_graph();
189 rg_add_node(&mut g, "a", PassKind::Render);
190 rg_add_node(&mut g, "b", PassKind::Render);
191 assert_eq!(rg_topo_sort(&g).len(), 2);
192 }
193
194 #[test]
195 fn json_has_nodes() {
196 assert!(rg_to_json(&new_render_graph()).contains("nodes"));
197 }
198}