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}