Skip to main content

vyre_debug/
naga_dump.rs

1use naga::{Block, Module, Statement};
2use std::collections::HashMap;
3
4pub struct NagaDump {
5    pub text: String,
6    // Maps handle index -> enclosing block path
7    block_paths: HashMap<u32, Vec<String>>,
8}
9
10impl NagaDump {
11    pub fn find(&self, handle: u32) -> Option<&Vec<String>> {
12        self.block_paths.get(&handle)
13    }
14}
15
16pub fn dump_naga_module(module: &Module) -> NagaDump {
17    let mut out = String::new();
18    let mut block_paths = HashMap::new();
19
20    out.push_str("=== globals ===\n");
21    for (handle, global) in module.global_variables.iter() {
22        let name = global.name.as_deref().unwrap_or("");
23        out.push_str(&format!(
24            "[{}] {} : {:?}, space={:?}\n",
25            handle.index(),
26            name,
27            global.ty,
28            global.space
29        ));
30    }
31    out.push_str("\n");
32
33    // We mainly care about entry points or the main function body.
34    // In vyre, there is typically one entry point.
35    if let Some(ep) = module.entry_points.first() {
36        let func = &ep.function;
37        out.push_str("=== local_variables ===\n");
38        for (handle, local) in func.local_variables.iter() {
39            let name = local.name.as_deref().unwrap_or("");
40            out.push_str(&format!(
41                "[{}] {:?} : {:?}\n",
42                handle.index(),
43                name,
44                local.ty
45            ));
46        }
47        out.push_str("\n");
48
49        out.push_str("=== expressions ===\n");
50        for (handle, expr) in func.expressions.iter() {
51            // Very simplified rendering
52            out.push_str(&format!("[{}] {:?}\n", handle.index(), expr));
53        }
54        out.push_str("\n");
55
56        out.push_str("=== body ===\n");
57        fn walk_block(
58            block: &Block,
59            path: &mut Vec<String>,
60            out: &mut String,
61            indent: usize,
62            block_paths: &mut HashMap<u32, Vec<String>>,
63            func: &naga::Function,
64        ) {
65            let ind = "  ".repeat(indent);
66            out.push_str(&format!("{}{{\n", ind));
67            for stmt in block.iter() {
68                out.push_str(&format!("{}  {:?}\n", ind, stmt));
69                match stmt {
70                    Statement::Emit(range) => {
71                        for h in range.clone() {
72                            block_paths.insert(h.index() as u32, path.clone());
73                        }
74                    }
75                    Statement::Block(b) => {
76                        path.push("Block".to_string());
77                        walk_block(b, path, out, indent + 1, block_paths, func);
78                        path.pop();
79                    }
80                    Statement::If {
81                        condition: _,
82                        accept,
83                        reject,
84                    } => {
85                        path.push("If.accept".to_string());
86                        walk_block(accept, path, out, indent + 1, block_paths, func);
87                        path.pop();
88                        path.push("If.reject".to_string());
89                        walk_block(reject, path, out, indent + 1, block_paths, func);
90                        path.pop();
91                    }
92                    Statement::Loop {
93                        body,
94                        continuing,
95                        break_if: _,
96                    } => {
97                        path.push("Loop.body".to_string());
98                        walk_block(body, path, out, indent + 1, block_paths, func);
99                        path.pop();
100                        path.push("Loop.continuing".to_string());
101                        walk_block(continuing, path, out, indent + 1, block_paths, func);
102                        path.pop();
103                    }
104                    _ => {}
105                }
106            }
107            out.push_str(&format!("{}}}\n", ind));
108        }
109
110        let mut root_path = vec!["root".to_string()];
111        walk_block(
112            &func.body,
113            &mut root_path,
114            &mut out,
115            0,
116            &mut block_paths,
117            func,
118        );
119    }
120
121    NagaDump {
122        text: out,
123        block_paths,
124    }
125}