naga/proc/overloads/
constructor_set.rs
1use crate::ir;
4use crate::proc::overloads::one_bits_iter::OneBitsIter;
5
6bitflags::bitflags! {
7 #[derive(Copy, Clone, Debug, PartialEq)]
9 pub(crate) struct ConstructorSet: u16 {
10 const SCALAR = 1 << 0;
11 const VEC2 = 1 << 1;
12 const VEC3 = 1 << 2;
13 const VEC4 = 1 << 3;
14 const MAT2X2 = 1 << 4;
15 const MAT2X3 = 1 << 5;
16 const MAT2X4 = 1 << 6;
17 const MAT3X2 = 1 << 7;
18 const MAT3X3 = 1 << 8;
19 const MAT3X4 = 1 << 9;
20 const MAT4X2 = 1 << 10;
21 const MAT4X3 = 1 << 11;
22 const MAT4X4 = 1 << 12;
23
24 const VECN = Self::VEC2.bits()
25 | Self::VEC3.bits()
26 | Self::VEC4.bits();
27 }
28}
29
30impl ConstructorSet {
31 pub const fn singleton(inner: &ir::TypeInner) -> ConstructorSet {
33 use ir::TypeInner as Ti;
34 use ir::VectorSize as Vs;
35 match *inner {
36 Ti::Scalar(_) => Self::SCALAR,
37 Ti::Vector { size, scalar: _ } => match size {
38 Vs::Bi => Self::VEC2,
39 Vs::Tri => Self::VEC3,
40 Vs::Quad => Self::VEC4,
41 },
42 Ti::Matrix {
43 columns,
44 rows,
45 scalar: _,
46 } => match (columns, rows) {
47 (Vs::Bi, Vs::Bi) => Self::MAT2X2,
48 (Vs::Bi, Vs::Tri) => Self::MAT2X3,
49 (Vs::Bi, Vs::Quad) => Self::MAT2X4,
50 (Vs::Tri, Vs::Bi) => Self::MAT3X2,
51 (Vs::Tri, Vs::Tri) => Self::MAT3X3,
52 (Vs::Tri, Vs::Quad) => Self::MAT3X4,
53 (Vs::Quad, Vs::Bi) => Self::MAT4X2,
54 (Vs::Quad, Vs::Tri) => Self::MAT4X3,
55 (Vs::Quad, Vs::Quad) => Self::MAT4X4,
56 },
57 _ => Self::empty(),
58 }
59 }
60
61 pub const fn is_singleton(self) -> bool {
62 self.bits().is_power_of_two()
63 }
64
65 pub fn members(self) -> impl Iterator<Item = ConstructorSet> {
69 OneBitsIter::new(self.bits() as u64).map(|bit| Self::from_bits(bit as u16).unwrap())
70 }
71
72 pub fn size(self) -> ConstructorSize {
78 use ir::VectorSize as Vs;
79 use ConstructorSize as Cs;
80
81 match self {
82 ConstructorSet::SCALAR => Cs::Scalar,
83 ConstructorSet::VEC2 => Cs::Vector(Vs::Bi),
84 ConstructorSet::VEC3 => Cs::Vector(Vs::Tri),
85 ConstructorSet::VEC4 => Cs::Vector(Vs::Quad),
86 ConstructorSet::MAT2X2 => Cs::Matrix {
87 columns: Vs::Bi,
88 rows: Vs::Bi,
89 },
90 ConstructorSet::MAT2X3 => Cs::Matrix {
91 columns: Vs::Bi,
92 rows: Vs::Tri,
93 },
94 ConstructorSet::MAT2X4 => Cs::Matrix {
95 columns: Vs::Bi,
96 rows: Vs::Quad,
97 },
98 ConstructorSet::MAT3X2 => Cs::Matrix {
99 columns: Vs::Tri,
100 rows: Vs::Bi,
101 },
102 ConstructorSet::MAT3X3 => Cs::Matrix {
103 columns: Vs::Tri,
104 rows: Vs::Tri,
105 },
106 ConstructorSet::MAT3X4 => Cs::Matrix {
107 columns: Vs::Tri,
108 rows: Vs::Quad,
109 },
110 ConstructorSet::MAT4X2 => Cs::Matrix {
111 columns: Vs::Quad,
112 rows: Vs::Bi,
113 },
114 ConstructorSet::MAT4X3 => Cs::Matrix {
115 columns: Vs::Quad,
116 rows: Vs::Tri,
117 },
118 ConstructorSet::MAT4X4 => Cs::Matrix {
119 columns: Vs::Quad,
120 rows: Vs::Quad,
121 },
122 _ => unreachable!("ConstructorSet was not a singleton"),
123 }
124 }
125}
126
127#[derive(Clone, Copy)]
129pub enum ConstructorSize {
130 Scalar,
134
135 Vector(ir::VectorSize),
137
138 Matrix {
140 columns: ir::VectorSize,
141 rows: ir::VectorSize,
142 },
143}
144
145impl ConstructorSize {
146 pub const fn to_inner(self, scalar: ir::Scalar) -> ir::TypeInner {
150 match self {
151 Self::Scalar => ir::TypeInner::Scalar(scalar),
152 Self::Vector(size) => ir::TypeInner::Vector { size, scalar },
153 Self::Matrix { columns, rows } => ir::TypeInner::Matrix {
154 columns,
155 rows,
156 scalar,
157 },
158 }
159 }
160}
161
162macro_rules! constructor_set {
163 ( $( $constr:ident )|* ) => {
164 {
165 use $crate::proc::overloads::constructor_set::ConstructorSet;
166 ConstructorSet::empty()
167 $(
168 .union(ConstructorSet::$constr)
169 )*
170 }
171 }
172}
173
174pub(in crate::proc::overloads) use constructor_set;