#![allow(clippy::new_without_default)]
mod arena;
pub mod back;
pub mod front;
pub mod proc;
pub use crate::arena::{Arena, Handle};
use std::{
collections::{HashMap, HashSet},
hash::BuildHasherDefault,
};
pub type FastHashMap<K, T> = HashMap<K, T, BuildHasherDefault<fxhash::FxHasher>>;
pub type FastHashSet<K> = HashSet<K, BuildHasherDefault<fxhash::FxHasher>>;
#[derive(Clone, Debug)]
pub struct Header {
pub version: (u8, u8, u8),
pub generator: u32,
}
pub type Bytes = u8;
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum VectorSize {
Bi = 2,
Tri = 3,
Quad = 4,
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ScalarKind {
Sint,
Uint,
Float,
Bool,
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ArraySize {
Static(spirv::Word),
Dynamic,
}
#[derive(Clone, Debug, PartialEq)]
pub struct StructMember {
pub name: Option<String>,
pub binding: Option<Binding>,
pub ty: Handle<Type>,
}
bitflags::bitflags! {
pub struct ImageFlags: u32 {
const ARRAYED = 0x1;
const MULTISAMPLED = 0x2;
const SAMPLED = 0x4;
const CAN_LOAD = 0x10;
const CAN_STORE = 0x20;
}
}
#[derive(Debug, PartialEq)]
pub struct Type {
pub name: Option<String>,
pub inner: TypeInner,
}
#[derive(Clone, Debug, PartialEq)]
pub enum TypeInner {
Scalar {
kind: ScalarKind,
width: Bytes,
},
Vector {
size: VectorSize,
kind: ScalarKind,
width: Bytes,
},
Matrix {
columns: VectorSize,
rows: VectorSize,
kind: ScalarKind,
width: Bytes,
},
Pointer {
base: Handle<Type>,
class: spirv::StorageClass,
},
Array {
base: Handle<Type>,
size: ArraySize,
},
Struct {
members: Vec<StructMember>,
},
Image {
base: Handle<Type>,
dim: spirv::Dim,
flags: ImageFlags,
},
Sampler {
comparison: bool,
},
}
#[derive(Debug, PartialEq)]
pub struct Constant {
pub name: Option<String>,
pub specialization: Option<spirv::Word>,
pub inner: ConstantInner,
pub ty: Handle<Type>,
}
#[derive(Clone, Debug, PartialEq)]
pub enum ConstantInner {
Sint(i64),
Uint(u64),
Float(f64),
Bool(bool),
Composite(Vec<Handle<Constant>>),
}
#[derive(Clone, Debug, PartialEq)]
pub enum Binding {
BuiltIn(spirv::BuiltIn),
Location(spirv::Word),
Descriptor {
set: spirv::Word,
binding: spirv::Word,
},
}
bitflags::bitflags! {
pub struct GlobalUse: u8 {
const LOAD = 0x1;
const STORE = 0x2;
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct GlobalVariable {
pub name: Option<String>,
pub class: spirv::StorageClass,
pub binding: Option<Binding>,
pub ty: Handle<Type>,
}
#[derive(Clone, Debug)]
pub struct LocalVariable {
pub name: Option<String>,
pub ty: Handle<Type>,
pub init: Option<Handle<Expression>>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum UnaryOperator {
Negate,
Not,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum BinaryOperator {
Add,
Subtract,
Multiply,
Divide,
Modulo,
Equal,
NotEqual,
Less,
LessEqual,
Greater,
GreaterEqual,
And,
ExclusiveOr,
InclusiveOr,
LogicalAnd,
LogicalOr,
ShiftLeftLogical,
ShiftRightLogical,
ShiftRightArithmetic,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum IntrinsicFunction {
Any,
All,
IsNan,
IsInf,
IsFinite,
IsNormal,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum DerivativeAxis {
X,
Y,
Width,
}
#[derive(Clone, Debug)]
pub enum Expression {
Access {
base: Handle<Expression>,
index: Handle<Expression>,
},
AccessIndex {
base: Handle<Expression>,
index: u32,
},
Constant(Handle<Constant>),
Compose {
ty: Handle<Type>,
components: Vec<Handle<Expression>>,
},
FunctionParameter(u32),
GlobalVariable(Handle<GlobalVariable>),
LocalVariable(Handle<LocalVariable>),
Load {
pointer: Handle<Expression>,
},
ImageSample {
image: Handle<Expression>,
sampler: Handle<Expression>,
coordinate: Handle<Expression>,
},
Unary {
op: UnaryOperator,
expr: Handle<Expression>,
},
Binary {
op: BinaryOperator,
left: Handle<Expression>,
right: Handle<Expression>,
},
Intrinsic {
fun: IntrinsicFunction,
argument: Handle<Expression>,
},
DotProduct(Handle<Expression>, Handle<Expression>),
CrossProduct(Handle<Expression>, Handle<Expression>),
Derivative {
axis: DerivativeAxis,
expr: Handle<Expression>,
},
Call {
name: String,
arguments: Vec<Handle<Expression>>,
},
}
pub type Block = Vec<Statement>;
#[derive(Clone, Debug)]
pub struct FallThrough;
#[derive(Clone, Debug)]
pub enum Statement {
Empty,
Block(Block),
If {
condition: Handle<Expression>,
accept: Block,
reject: Block,
},
Switch {
selector: Handle<Expression>,
cases: FastHashMap<i32, (Block, Option<FallThrough>)>,
default: Block,
},
Loop {
body: Block,
continuing: Block,
},
Break,
Continue,
Return {
value: Option<Handle<Expression>>,
},
Kill,
Store {
pointer: Handle<Expression>,
value: Handle<Expression>,
},
}
#[derive(Debug)]
pub struct Function {
pub name: Option<String>,
pub control: spirv::FunctionControl,
pub parameter_types: Vec<Handle<Type>>,
pub return_type: Option<Handle<Type>>,
pub global_usage: Vec<GlobalUse>,
pub local_variables: Arena<LocalVariable>,
pub expressions: Arena<Expression>,
pub body: Block,
}
#[derive(Debug)]
pub struct EntryPoint {
pub exec_model: spirv::ExecutionModel,
pub name: String,
pub function: Handle<Function>,
}
#[derive(Debug)]
pub struct Module {
pub header: Header,
pub types: Arena<Type>,
pub constants: Arena<Constant>,
pub global_variables: Arena<GlobalVariable>,
pub functions: Arena<Function>,
pub entry_points: Vec<EntryPoint>,
}