1#![allow(clippy::new_without_default)]
2
3mod arena;
4pub mod back;
5pub mod front;
6pub mod proc;
7
8pub use crate::arena::{Arena, Handle};
9
10use std::{
11 collections::{HashMap, HashSet},
12 hash::BuildHasherDefault,
13 num::NonZeroU32,
14};
15
16pub type FastHashMap<K, T> = HashMap<K, T, BuildHasherDefault<fxhash::FxHasher>>;
17pub type FastHashSet<K> = HashSet<K, BuildHasherDefault<fxhash::FxHasher>>;
18
19#[derive(Clone, Debug)]
20pub struct Header {
21 pub version: (u8, u8, u8),
22 pub generator: u32,
23}
24
25pub type Bytes = u8;
26
27#[repr(u8)]
28#[derive(Clone, Copy, Debug, PartialEq)]
29pub enum VectorSize {
30 Bi = 2,
31 Tri = 3,
32 Quad = 4,
33}
34
35#[repr(u8)]
36#[derive(Clone, Copy, Debug, PartialEq)]
37pub enum ScalarKind {
38 Sint,
39 Uint,
40 Float,
41 Bool,
42}
43
44#[repr(u8)]
45#[derive(Clone, Copy, Debug, PartialEq)]
46pub enum ArraySize {
47 Static(spirv::Word),
48 Dynamic,
49}
50
51#[derive(Clone, Debug, PartialEq)]
53pub struct StructMember {
54 pub name: Option<String>,
55 pub binding: Option<Binding>,
56 pub ty: Handle<Type>,
57 pub offset: spirv::Word,
58}
59
60bitflags::bitflags! {
61 pub struct ImageFlags: u32 {
62 const ARRAYED = 0x1;
63 const MULTISAMPLED = 0x2;
64 const SAMPLED = 0x4;
65 const CAN_LOAD = 0x10;
66 const CAN_STORE = 0x20;
67 }
68}
69
70#[derive(Debug, PartialEq)]
71pub struct Type {
72 pub name: Option<String>,
73 pub inner: TypeInner,
74}
75
76#[derive(Clone, Debug, PartialEq)]
78pub enum TypeInner {
79 Scalar {
80 kind: ScalarKind,
81 width: Bytes,
82 },
83 Vector {
84 size: VectorSize,
85 kind: ScalarKind,
86 width: Bytes,
87 },
88 Matrix {
89 columns: VectorSize,
90 rows: VectorSize,
91 kind: ScalarKind,
92 width: Bytes,
93 },
94 Pointer {
95 base: Handle<Type>,
96 class: spirv::StorageClass,
97 },
98 Array {
99 base: Handle<Type>,
100 size: ArraySize,
101 stride: Option<NonZeroU32>,
102 },
103 Struct {
104 members: Vec<StructMember>,
105 },
106 Image {
107 base: Handle<Type>,
108 dim: spirv::Dim,
109 flags: ImageFlags,
110 },
111 Sampler {
112 comparison: bool,
113 },
114}
115
116#[derive(Debug, PartialEq)]
117pub struct Constant {
118 pub name: Option<String>,
119 pub specialization: Option<spirv::Word>,
120 pub inner: ConstantInner,
121 pub ty: Handle<Type>,
122}
123
124#[derive(Clone, Debug, PartialEq)]
126pub enum ConstantInner {
127 Sint(i64),
128 Uint(u64),
129 Float(f64),
130 Bool(bool),
131 Composite(Vec<Handle<Constant>>),
132}
133
134#[derive(Clone, Debug, PartialEq)]
135pub enum Binding {
136 BuiltIn(spirv::BuiltIn),
137 Location(spirv::Word),
138 Descriptor {
139 set: spirv::Word,
140 binding: spirv::Word,
141 },
142}
143
144bitflags::bitflags! {
145 pub struct GlobalUse: u8 {
146 const LOAD = 0x1;
147 const STORE = 0x2;
148 }
149}
150
151#[derive(Clone, Debug, PartialEq)]
152pub struct GlobalVariable {
153 pub name: Option<String>,
154 pub class: spirv::StorageClass,
155 pub binding: Option<Binding>,
156 pub ty: Handle<Type>,
157}
158
159#[derive(Clone, Debug)]
160pub struct LocalVariable {
161 pub name: Option<String>,
162 pub ty: Handle<Type>,
163 pub init: Option<Handle<Expression>>,
164}
165
166#[derive(Clone, Copy, Debug, PartialEq)]
167pub enum UnaryOperator {
168 Negate,
169 Not,
170}
171
172#[derive(Clone, Copy, Debug, PartialEq)]
173pub enum BinaryOperator {
174 Add,
175 Subtract,
176 Multiply,
177 Divide,
178 Modulo,
179 Equal,
180 NotEqual,
181 Less,
182 LessEqual,
183 Greater,
184 GreaterEqual,
185 And,
186 ExclusiveOr,
187 InclusiveOr,
188 LogicalAnd,
189 LogicalOr,
190 ShiftLeftLogical,
191 ShiftRightLogical,
192 ShiftRightArithmetic,
193}
194
195#[derive(Clone, Copy, Debug, PartialEq)]
196pub enum IntrinsicFunction {
197 Any,
198 All,
199 IsNan,
200 IsInf,
201 IsFinite,
202 IsNormal,
203}
204
205#[derive(Clone, Copy, Debug, PartialEq)]
206pub enum DerivativeAxis {
207 X,
208 Y,
209 Width,
210}
211
212#[derive(Clone, Debug)]
213pub enum Expression {
214 Access {
215 base: Handle<Expression>,
216 index: Handle<Expression>, },
218 AccessIndex {
219 base: Handle<Expression>,
220 index: u32,
221 },
222 Constant(Handle<Constant>),
223 Compose {
224 ty: Handle<Type>,
225 components: Vec<Handle<Expression>>,
226 },
227 FunctionParameter(u32),
228 GlobalVariable(Handle<GlobalVariable>),
229 LocalVariable(Handle<LocalVariable>),
230 Load {
231 pointer: Handle<Expression>,
232 },
233 ImageSample {
234 image: Handle<Expression>,
235 sampler: Handle<Expression>,
236 coordinate: Handle<Expression>,
237 },
238 Unary {
239 op: UnaryOperator,
240 expr: Handle<Expression>,
241 },
242 Binary {
243 op: BinaryOperator,
244 left: Handle<Expression>,
245 right: Handle<Expression>,
246 },
247 Intrinsic {
248 fun: IntrinsicFunction,
249 argument: Handle<Expression>,
250 },
251 DotProduct(Handle<Expression>, Handle<Expression>),
252 CrossProduct(Handle<Expression>, Handle<Expression>),
253 Derivative {
254 axis: DerivativeAxis,
255 expr: Handle<Expression>,
257 },
258 Call {
259 name: String,
260 arguments: Vec<Handle<Expression>>,
261 },
262}
263
264pub type Block = Vec<Statement>;
265
266#[derive(Clone, Debug)]
268pub struct FallThrough;
269
270#[derive(Clone, Debug)]
272pub enum Statement {
273 Empty,
274 Block(Block),
275 If {
276 condition: Handle<Expression>, accept: Block,
278 reject: Block,
279 },
280 Switch {
281 selector: Handle<Expression>, cases: FastHashMap<i32, (Block, Option<FallThrough>)>,
283 default: Block,
284 },
285 Loop {
286 body: Block,
287 continuing: Block,
288 },
289 Break,
291 Continue,
292 Return {
293 value: Option<Handle<Expression>>,
294 },
295 Kill,
296 Store {
297 pointer: Handle<Expression>,
298 value: Handle<Expression>,
299 },
300}
301
302#[derive(Debug)]
303pub struct Function {
304 pub name: Option<String>,
305 pub control: spirv::FunctionControl,
306 pub parameter_types: Vec<Handle<Type>>,
307 pub return_type: Option<Handle<Type>>,
308 pub global_usage: Vec<GlobalUse>,
309 pub local_variables: Arena<LocalVariable>,
310 pub expressions: Arena<Expression>,
311 pub body: Block,
312}
313
314#[derive(Debug)]
315pub struct EntryPoint {
316 pub exec_model: spirv::ExecutionModel,
317 pub name: String,
318 pub function: Handle<Function>,
319}
320
321#[derive(Debug)]
322pub struct Module {
323 pub header: Header,
324 pub types: Arena<Type>,
325 pub constants: Arena<Constant>,
326 pub global_variables: Arena<GlobalVariable>,
327 pub functions: Arena<Function>,
328 pub entry_points: Vec<EntryPoint>,
329}