spirq/
instr.rs

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
49// Be aware that the order of the read methods is important.
50define_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}