1use spq_core::error::anyhow;
2use std::convert::TryFrom;
3
4use crate::{parse::Instr, spirv::*};
5
6type InstrId = u32;
7type FunctionId = InstrId;
8type TypeId = InstrId;
9type VariableId = InstrId;
10type ConstantId = InstrId;
11type SpecConstantId = InstrId;
12
13type MemberIdx = u32;
14
15#[macro_export]
16macro_rules! define_ops {
17 (read_enum: $type:ty: $operands:expr) => {
18 {
19 <$type>::from_u32($operands.read_u32()?)
20 .ok_or_else(|| anyhow!("invalid enum value"))?
21 }
22 };
23 ($read_fn:ident: $type:ty: $operands:expr) => {
24 {
25 $operands.$read_fn()?
26 }
27 };
28 ($($opcode:ident { $($field:ident: $type:ty = $read_fn:tt(),)+ })+) => {
29 $(
30 pub struct $opcode<'a> {
31 $( pub $field: $type, )*
32 _ph: ::std::marker::PhantomData<&'a ()>,
33 }
34 impl<'a> TryFrom<&'a Instr> for $opcode<'a> {
35 type Error = ::spq_core::error::Error;
36 fn try_from(instr: &'a Instr) -> ::spq_core::error::Result<Self> {
37 let mut operands = instr.operands();
38 let op = $opcode {
39 $( $field: define_ops!($read_fn: $type: operands), )+
40 _ph: ::std::marker::PhantomData,
41 };
42 Ok(op)
43 }
44 }
45 )+
46 };
47}
48
49define_ops! {
51 OpExtInstImport {
52 instr_set_id: InstrId = read_u32(),
53 name: &'a str = read_str(),
54 }
55
56 OpMemoryModel {
57 addr_model: AddressingModel = read_enum(),
58 mem_model: MemoryModel = read_enum(),
59 }
60
61 OpEntryPoint {
62 exec_model: ExecutionModel = read_enum(),
63 func_id: FunctionId = read_u32(),
64 name: &'a str = read_str(),
65 }
66
67 OpExecutionModeCommonSPQ {
68 func_id: FunctionId = read_u32(),
69 execution_mode: ExecutionMode = read_enum(),
70 params: &'a [u32] = read_list(),
71 }
72
73 OpName {
74 target_id: InstrId = read_u32(),
75 name: &'a str = read_str(),
76 }
77 OpMemberName {
78 target_id: InstrId = read_u32(),
79 member_idx: MemberIdx = read_u32(),
80 name: &'a str = read_str(),
81 }
82
83 OpDecorate {
84 target_id: InstrId = read_u32(),
85 deco: Decoration = read_enum(),
86 params: &'a [u32] = read_list(),
87 }
88 OpMemberDecorate {
89 target_id: InstrId = read_u32(),
90 member_idx: MemberIdx = read_u32(),
91 deco: Decoration = read_enum(),
92 params: &'a [u32] = read_list(),
93 }
94
95 OpTypeVoid {
96 ty_id: TypeId = read_u32(),
97 }
98 OpTypeBool {
99 ty_id: TypeId = read_u32(),
100 }
101 OpTypeInt {
102 ty_id: TypeId = read_u32(),
103 bits: u32 = read_u32(),
104 is_signed: bool = read_bool(),
105 }
106 OpTypeFloat {
107 ty_id: TypeId = read_u32(),
108 bits: u32 = read_u32(),
109 }
110 OpTypeVector {
111 ty_id: TypeId = read_u32(),
112 scalar_ty_id: TypeId = read_u32(),
113 nscalar: u32 = read_u32(),
114 }
115 OpTypeMatrix {
116 ty_id: TypeId = read_u32(),
117 vector_ty_id: TypeId = read_u32(),
118 nvector: u32 = read_u32(),
119 }
120 OpTypeImage {
121 ty_id: TypeId = read_u32(),
122 scalar_ty_id: TypeId = read_u32(),
123 dim: Dim = read_enum(),
124 is_depth: u32 = read_u32(),
125 is_array: bool = read_bool(),
126 is_multisampled: bool = read_bool(),
127 is_sampled: u32 = read_u32(),
128 color_fmt: ImageFormat = read_enum(),
129 }
130 OpTypeSampler {
131 ty_id: TypeId = read_u32(),
132 }
133 OpTypeSampledImage {
134 ty_id: TypeId = read_u32(),
135 image_ty_id: TypeId = read_u32(),
136 }
137 OpTypeArray {
138 ty_id: TypeId = read_u32(),
139 element_ty_id: TypeId = read_u32(),
140 nelement_const_id: ConstantId = read_u32(),
141 }
142 OpTypeRuntimeArray {
143 ty_id: TypeId = read_u32(),
144 element_ty_id: TypeId = read_u32(),
145 }
146 OpTypeStruct {
147 ty_id: TypeId = read_u32(),
148 member_ty_ids: &'a [TypeId] = read_list(),
149 }
150 OpTypePointer {
151 ty_id: TypeId = read_u32(),
152 store_cls: StorageClass = read_enum(),
153 target_ty_id: TypeId = read_u32(),
154 }
155 OpTypeForwardPointer {
156 ty_id: TypeId = read_u32(),
157 store_cls: StorageClass = read_enum(),
158 }
159 OpConstantTrue {
160 ty_id: TypeId = read_u32(),
161 const_id: ConstantId = read_u32(),
162 }
163 OpConstantFalse {
164 ty_id: TypeId = read_u32(),
165 const_id: ConstantId = read_u32(),
166 }
167 OpConstant {
168 ty_id: TypeId = read_u32(),
169 const_id: ConstantId = read_u32(),
170 value: &'a [u32] = read_list(),
171 }
172 OpSpecConstantTrue {
173 ty_id: TypeId = read_u32(),
174 spec_const_id: SpecConstantId = read_u32(),
175 }
176 OpSpecConstantFalse {
177 ty_id: TypeId = read_u32(),
178 spec_const_id: SpecConstantId = read_u32(),
179 }
180 OpSpecConstant {
181 ty_id: TypeId = read_u32(),
182 spec_const_id: SpecConstantId = read_u32(),
183 value: &'a [u32] = read_list(),
184 }
185 OpSpecConstantComposite {
186 ty_id: TypeId = read_u32(),
187 spec_const_id: SpecConstantId = read_u32(),
188 value: &'a [SpecConstantId] = read_list(),
189 }
190 OpVariable {
191 ty_id: TypeId = read_u32(),
192 var_id: VariableId = read_u32(),
193 store_cls: StorageClass = read_enum(),
194 }
195
196 OpFunction {
197 return_ty_id: TypeId = read_u32(),
198 func_id: TypeId = read_u32(),
199 }
200 OpFunctionCall {
201 return_ty_id: TypeId = read_u32(),
202 return_id: InstrId = read_u32(),
203 func_id: FunctionId = read_u32(),
204 }
205 OpLoad {
206 return_ty_id: TypeId = read_u32(),
207 return_id: InstrId = read_u32(),
208 var_id: VariableId = read_u32(),
209 }
210 OpStore {
211 var_id: VariableId = read_u32(),
212 }
213 OpAccessChain {
214 var_ty_id: TypeId = read_u32(),
215 var_id: VariableId = read_u32(),
216 accessed_var_id: VariableId = read_u32(),
217 }
218 OpTypeAccelerationStructureKHR {
219 ty_id: TypeId = read_u32(),
220 }
221
222 OpConstantScalarCommonSPQ {
223 ty_id: TypeId = read_u32(),
224 const_id: ConstantId = read_u32(),
225 value: &'a [u32] = read_list(),
226 }
227 OpSpecConstantHeadSPQ {
228 ty_id: TypeId = read_u32(),
229 spec_const_id: SpecConstantId = read_u32(),
230 opcode: u32 = read_u32(),
231 }
232 OpSpecConstantUnaryOpCommonSPQ {
233 ty_id: TypeId = read_u32(),
234 spec_const_id: SpecConstantId = read_u32(),
235 opcode: u32 = read_u32(),
236 a_id: SpecConstantId = read_u32(),
237 }
238 OpSpecConstantBinaryOpCommonSPQ {
239 ty_id: TypeId = read_u32(),
240 spec_const_id: SpecConstantId = read_u32(),
241 opcode: u32 = read_u32(),
242 a_id: SpecConstantId = read_u32(),
243 b_id: SpecConstantId = read_u32(),
244 }
245 OpSpecConstantTertiaryOpCommonSPQ {
246 ty_id: TypeId = read_u32(),
247 spec_const_id: SpecConstantId = read_u32(),
248 opcode: u32 = read_u32(),
249 a_id: SpecConstantId = read_u32(),
250 b_id: SpecConstantId = read_u32(),
251 c_id: SpecConstantId = read_u32(),
252 }
253 OpTypeRayQueryKHR {
254 ty_id: TypeId = read_u32(),
255 }
256}