use super::request::{Dim, ImageAtomicOp, QueryKind};
use iridia::ResourceId;
pub(super) type Reg = [u32; 4];
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum BinOp {
AddF,
SubF,
MulF,
DivF,
ModF,
AddU,
SubU,
MulU,
DivU,
ModU,
And,
Or,
Xor,
Shl,
ShrU,
ShrI,
EqW,
NeW,
EqF,
NeF,
LtF,
LeF,
GtF,
GeF,
LtU,
LeU,
GtU,
GeU,
LtI,
LeI,
GtI,
GeI,
LAnd,
LOr,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum UnOp {
NegF,
NegI,
Not,
BitNot,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum CvtOp {
F2I,
F2U,
I2F,
U2F,
B2F,
B2U,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum MathOp {
AbsF,
AbsI,
MinF,
MaxF,
MinU,
MaxU,
MinI,
MaxI,
ClampF,
SatF,
Floor,
Ceil,
Trunc,
Round,
Fract,
Exp2,
Log2,
Sin,
Cos,
QuantizeF16,
Tan,
Asin,
Acos,
Atan,
Sinh,
Cosh,
Tanh,
Fma,
Sqrt,
Rsqrt,
Dot,
Popcnt,
RevBits,
Clz,
Ctz,
PackHalf,
UnpackHalf,
Mix,
Normalize,
Pow,
SignF,
SignI,
All,
Any,
IsNan,
IsInf,
}
#[derive(Clone, Copy, Debug)]
pub(super) enum Loc {
Local(u32),
Global(u32, u32),
Elem(u32, u32, Pick),
}
impl Loc {
pub(super) fn slot(&self) -> Option<u32> {
match self {
Loc::Elem(_, _, Pick::Slot(s)) => Some(*s),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug)]
pub(super) struct Ptr {
pub loc: Loc,
pub dynamic: Option<(u32, u32, u32)>,
}
#[derive(Clone, Debug)]
pub(super) enum Op {
Swizzle {
src: u32,
pat: [u8; 4],
n: u8,
},
Splat {
src: u32,
n: u8,
},
Compose {
parts: [(u32, u8); 4],
np: u8,
},
Lane {
src: u32,
i: u8,
},
Load {
loc: Loc,
n: u8,
},
LoadLanes {
loc: Loc,
offs: [u8; 4],
n: u8,
},
LoadDyn {
ptr: Ptr,
n: u8,
},
Un {
op: UnOp,
src: u32,
n: u8,
},
Bin {
op: BinOp,
a: u32,
b: u32,
n: u8,
a1: bool,
b1: bool,
},
Select {
c: u32,
a: u32,
b: u32,
n: u8,
c1: bool,
},
Cvt {
op: CvtOp,
src: u32,
n: u8,
},
Math {
f: MathOp,
a: u32,
b: u32,
c: u32,
n: u8,
c1: bool,
},
Deriv {
src: u32,
axis: u8,
fine: bool,
n: u8,
prov: Option<[(u32, u8); 4]>,
},
Sample {
tex: Res,
smp: Res,
coord: u32,
cn: u8,
layer: Option<u32>,
level: LevelOp,
dim: Dim,
offset: [i32; 3],
gather: Option<u8>,
depth_ref: Option<u32>,
depth: bool,
},
Texel {
tex: Res,
coord: u32,
cn: u8,
dim: Dim,
storage: bool,
layer: Option<u32>,
sample: Option<u32>,
mip: Option<u32>,
},
Query {
tex: Res,
dim: Dim,
kind: QueryKind,
level: Option<u32>,
},
CopyWords {
src: Loc,
dst: u32,
words: u32,
},
RqHit {
q: u32,
committed: bool,
first: u32,
},
ArrLen {
gid: u32,
elem_words: u32,
pick: Option<Pick>,
},
}
#[derive(Clone, Copy, Debug)]
pub(super) enum Pick {
One,
Fixed(u32),
Slot(u32),
}
#[derive(Clone, Copy, Debug)]
pub(super) struct Res {
pub id: ResourceId,
pub pick: Pick,
pub count: u32,
}
impl Res {
pub(super) fn slot(&self) -> Option<u32> {
match self.pick {
Pick::Slot(s) => Some(s),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug)]
pub(super) enum LevelOp {
Auto,
Zero,
Exact(u32),
Bias(u32),
Gradient(u32, u32),
}
#[derive(Clone, Copy, Debug)]
pub(super) enum Member {
Reg(u32, u8),
Mem {
word: u32,
count: u32,
width: u8,
keep: Option<u32>,
},
}
#[derive(Clone, Debug)]
pub(super) enum St {
Run(u32, u32),
Store {
loc: Loc,
src: u32,
n: u8,
},
StoreDyn {
ptr: Ptr,
src: u32,
n: u8,
},
ImageStore {
tex: Res,
dim: Dim,
coord: u32,
cn: u8,
layer: Option<u32>,
value: u32,
vn: u8,
},
ImageAtomic {
tex: Res,
dim: Dim,
coord: u32,
cn: u8,
layer: Option<u32>,
op: ImageAtomicOp,
signed: bool,
value: u32,
result: Option<u32>,
},
Atomic {
ptr: Ptr,
fun: AtomOp,
signed: bool,
value: u32,
compare: Option<u32>,
result: Option<u32>,
exchanged: Option<u32>,
},
Barrier,
StoreAgg {
loc: Loc,
members: Vec<(u32, u8)>,
},
RqInit {
q: u32,
scene: ResourceId,
flags: u32,
mask: u32,
tmin: u32,
tmax: u32,
origin: u32,
direction: u32,
},
RqProceed {
q: u32,
result: u32,
},
RqConfirm {
q: u32,
},
RtTrace {
scene: ResourceId,
operands: [u32; 9],
payload: (u32, u32),
},
RtReport {
t: u32,
kind: u32,
attributes: (u32, u32),
result: Option<u32>,
},
RtCall {
index: u32,
parameter: (u32, u32),
},
RtDecide(super::run::Decision),
RqGenerate {
q: u32,
t: u32,
},
RqTerminate {
q: u32,
},
WaveBallot {
predicate: Option<u32>,
result: u32,
},
WaveGather {
mode: WaveGather,
value: u32,
n: u8,
result: u32,
},
WaveOp {
op: WaveOp,
scan: WaveScan,
value: u32,
n: u8,
kind: WaveKind,
result: u32,
},
If {
c: u32,
a: Vec<St>,
r: Vec<St>,
},
Loop {
body: Vec<St>,
cont: Vec<St>,
break_if: Option<u32>,
},
Switch {
sel: u32,
cases: Vec<(Option<u32>, bool, Vec<St>)>,
},
Break,
Continue,
Return(Vec<Member>),
Kill,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum WaveGather {
First,
Lane(u32),
Shuffle(u32),
Down(u32),
Up(u32),
Xor(u32),
QuadLane(u32),
QuadSwap(u32),
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum WaveOp {
All,
Any,
Add,
Mul,
Min,
Max,
And,
Or,
Xor,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum WaveScan {
Reduce,
Inclusive,
Exclusive,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum WaveKind {
F,
U,
I,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum AtomOp {
Add,
Sub,
And,
Or,
Xor,
Min,
Max,
Exchange,
CompareExchange,
}
#[derive(Clone, Debug)]
pub(super) enum GlobalKind {
Constants(ResourceId),
ConstantsArray(ResourceId, u32),
Private(Vec<u32>),
Storage(ResourceId),
StorageArray(ResourceId, u32),
Workgroup(u32),
}
#[derive(Clone, Debug)]
pub(super) struct GlobalDesc {
pub kind: GlobalKind,
pub elem_words: u32,
}
#[derive(Debug)]
pub struct Executable {
pub(super) ops: Vec<(u32, Op)>,
pub(super) body: Vec<St>,
pub(super) slots: usize,
pub(super) inits: Vec<(u32, Reg)>,
pub(super) args: Vec<(u32, u8)>,
pub(super) arg_at: Vec<usize>,
pub(super) arg_len: usize,
pub(super) pointer_args: Vec<(usize, u32, u32)>,
pub(super) array_args: Vec<(usize, u32, u32, u8)>,
pub(super) local_words: usize,
pub(super) globals: Vec<GlobalDesc>,
pub(super) flush_denormals: bool,
pub(super) workgroup: Option<[u32; 3]>,
pub(super) mesh_output: Option<(usize, u32)>,
pub(super) builtins: Vec<Option<naga::BuiltIn>>,
}