reflect_shader/
main.rs

1use core::slice;
2
3use spirv_layout::{LocationVariable, Module, PushConstantVariable, Type, UniformVariable};
4
5const PATH: &str = concat!(
6    env!("CARGO_MANIFEST_DIR"),
7    "/examples/reflect-shader/test2.spv"
8);
9
10fn main() {
11    {
12        let bytes = std::fs::read(PATH).unwrap();
13        let words = unsafe { slice::from_raw_parts(bytes.as_ptr() as *const u32, bytes.len() / 4) };
14        let module = Module::from_words(words).unwrap();
15
16        for ep in module.get_entry_points() {
17            println!("ENTRYPOINT {} {:?}", ep.name, ep.execution_model);
18
19            println!("=== INPUTS ===");
20            for var in &ep.inputs {
21                print_location_var(&module, var);
22            }
23
24            println!("=== OUTPUTS ===");
25            for var in &ep.outputs {
26                print_location_var(&module, var);
27            }
28
29            println!("=== UNIFORMS ===");
30            for var in &ep.uniforms {
31                print_uniform_var(&module, var);
32            }
33
34            println!("=== PUSH CONSTANTS ===");
35            for var in &ep.push_constants {
36                print_pc_var(&module, var);
37            }
38        }
39    }
40}
41
42fn print_uniform_var(module: &Module, var: &UniformVariable) {
43    print!("layout (set={}, binding={}) ", var.set, var.binding);
44
45    print_type(module, module.get_type(var.type_id).unwrap());
46
47    println!(
48        "{}; // size={}",
49        if let Some(name) = &var.name {
50            name
51        } else {
52            "<no-name>"
53        },
54        module.get_var_size(var).unwrap()
55    );
56}
57
58fn print_pc_var(module: &Module, var: &PushConstantVariable) {
59    print_type(module, module.get_type(var.type_id).unwrap());
60
61    println!(
62        "{}; // size={}",
63        if let Some(name) = &var.name {
64            name
65        } else {
66            "<no-name>"
67        },
68        module.get_var_size(var).unwrap()
69    );
70}
71
72fn print_location_var(module: &Module, var: &LocationVariable) {
73    print!("layout (location={}) ", var.location);
74
75    print_type(module, module.get_type(var.type_id).unwrap());
76
77    println!(
78        "{}; // size={}",
79        if let Some(name) = &var.name {
80            name
81        } else {
82            "<no-name>"
83        },
84        module.get_var_size(var).unwrap()
85    );
86}
87
88fn print_type(module: &Module, ty: &Type) {
89    match ty {
90        Type::Void => print!("void "),
91        Type::Bool => print!("bool "),
92        Type::Int32 => print!("int "),
93        Type::UInt32 => print!("uint "),
94        Type::Float32 => print!("float "),
95        Type::Vec2 => print!("vec2 "),
96        Type::Vec3 => print!("vec3 "),
97        Type::Vec4 => print!("vec4 "),
98        Type::Mat3 => print!("mat3 "),
99        Type::Mat4 => print!("mat4 "),
100        Type::Image2D { .. } => print!("image2D "),
101        Type::Sampler => print!("sampler "),
102        Type::SampledImage { .. } => print!("sampler2D "),
103        Type::Array {
104            element_type_id,
105            length,
106        } => {
107            print_type(module, module.get_type(*element_type_id).unwrap());
108            print!("[{}] ", length.unwrap_or(0));
109        }
110        Type::Struct { name, elements } => {
111            println!(
112                "struct {} {{",
113                name.as_ref().map(|n| n.as_str()).unwrap_or("<no-name>")
114            );
115
116            for elem in elements {
117                print!("    layout(");
118                if let Some(offset) = elem.offset {
119                    print!("offset={}", offset);
120                }
121                if let Some(Type::Mat3 | Type::Mat4) = module.get_type(elem.type_id) {
122                    print!(
123                        ", {}, stride={}",
124                        if elem.row_major {
125                            "row_major"
126                        } else {
127                            "col_major"
128                        },
129                        elem.stride
130                    );
131                }
132                print!(") ");
133
134                print_type(module, module.get_type(elem.type_id).unwrap());
135
136                println!(
137                    "{}; // size={}",
138                    if let Some(name) = &elem.name {
139                        name
140                    } else {
141                        "<no-name>"
142                    },
143                    module.get_member_size(elem).unwrap()
144                );
145            }
146
147            print!("}} ");
148        }
149        Type::Pointer {
150            storage_class: _,
151            pointed_type_id,
152        } => {
153            print_type(module, module.get_type(*pointed_type_id).unwrap());
154            print!("* ");
155        }
156        _ => print!("<unknown> "),
157    }
158}