1 // Generated from vec_mask.rs.tera template. Edit the template, not the generated file. 2 3 #[cfg(not(target_arch = "spirv"))] 4 use core::fmt; 5 use core::ops::*; 6 7 #[cfg(target_arch = "x86")] 8 use core::arch::x86::*; 9 #[cfg(target_arch = "x86_64")] 10 use core::arch::x86_64::*; 11 12 #[repr(C)] 13 union UnionCast { 14 a: [u32; 4], 15 v: BVec3A, 16 } 17 18 /// A 3-dimensional SIMD vector mask. 19 /// 20 /// This type is 16 byte aligned. 21 #[derive(Clone, Copy)] 22 #[repr(transparent)] 23 pub struct BVec3A(pub(crate) __m128); 24 25 const MASK: [u32; 2] = [0, 0xff_ff_ff_ff]; 26 27 impl BVec3A { 28 /// All false. 29 pub const FALSE: Self = Self::splat(false); 30 31 /// All true. 32 pub const TRUE: Self = Self::splat(true); 33 34 /// Creates a new vector mask. 35 #[inline(always)] 36 #[must_use] new(x: bool, y: bool, z: bool) -> Self37 pub const fn new(x: bool, y: bool, z: bool) -> Self { 38 unsafe { 39 UnionCast { 40 a: [MASK[x as usize], MASK[y as usize], MASK[z as usize], 0], 41 } 42 .v 43 } 44 } 45 46 /// Creates a vector with all elements set to `v`. 47 #[inline] 48 #[must_use] splat(v: bool) -> Self49 pub const fn splat(v: bool) -> Self { 50 Self::new(v, v, v) 51 } 52 53 /// Returns a bitmask with the lowest 3 bits set from the elements of `self`. 54 /// 55 /// A true element results in a `1` bit and a false element in a `0` bit. Element `x` goes 56 /// into the first lowest bit, element `y` into the second, etc. 57 #[inline] 58 #[must_use] bitmask(self) -> u3259 pub fn bitmask(self) -> u32 { 60 unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 } 61 } 62 63 /// Returns true if any of the elements are true, false otherwise. 64 #[inline] 65 #[must_use] any(self) -> bool66 pub fn any(self) -> bool { 67 self.bitmask() != 0 68 } 69 70 /// Returns true if all the elements are true, false otherwise. 71 #[inline] 72 #[must_use] all(self) -> bool73 pub fn all(self) -> bool { 74 self.bitmask() == 0x7 75 } 76 77 /// Tests the value at `index`. 78 /// 79 /// Panics if `index` is greater than 2. 80 #[inline] 81 #[must_use] test(&self, index: usize) -> bool82 pub fn test(&self, index: usize) -> bool { 83 match index { 84 0 => (self.bitmask() & (1 << 0)) != 0, 85 1 => (self.bitmask() & (1 << 1)) != 0, 86 2 => (self.bitmask() & (1 << 2)) != 0, 87 _ => panic!("index out of bounds"), 88 } 89 } 90 91 /// Sets the element at `index`. 92 /// 93 /// Panics if `index` is greater than 2. 94 #[inline] set(&mut self, index: usize, value: bool)95 pub fn set(&mut self, index: usize, value: bool) { 96 use crate::Vec3A; 97 let mut v = Vec3A(self.0); 98 v[index] = f32::from_bits(MASK[value as usize]); 99 *self = Self(v.0); 100 } 101 102 #[inline] 103 #[must_use] into_bool_array(self) -> [bool; 3]104 fn into_bool_array(self) -> [bool; 3] { 105 let bitmask = self.bitmask(); 106 [(bitmask & 1) != 0, (bitmask & 2) != 0, (bitmask & 4) != 0] 107 } 108 109 #[inline] 110 #[must_use] into_u32_array(self) -> [u32; 3]111 fn into_u32_array(self) -> [u32; 3] { 112 let bitmask = self.bitmask(); 113 [ 114 MASK[(bitmask & 1) as usize], 115 MASK[((bitmask >> 1) & 1) as usize], 116 MASK[((bitmask >> 2) & 1) as usize], 117 ] 118 } 119 } 120 121 impl Default for BVec3A { 122 #[inline] default() -> Self123 fn default() -> Self { 124 Self::FALSE 125 } 126 } 127 128 impl PartialEq for BVec3A { 129 #[inline] eq(&self, rhs: &Self) -> bool130 fn eq(&self, rhs: &Self) -> bool { 131 self.bitmask().eq(&rhs.bitmask()) 132 } 133 } 134 135 impl Eq for BVec3A {} 136 137 impl core::hash::Hash for BVec3A { 138 #[inline] hash<H: core::hash::Hasher>(&self, state: &mut H)139 fn hash<H: core::hash::Hasher>(&self, state: &mut H) { 140 self.bitmask().hash(state); 141 } 142 } 143 144 impl BitAnd for BVec3A { 145 type Output = Self; 146 #[inline] bitand(self, rhs: Self) -> Self147 fn bitand(self, rhs: Self) -> Self { 148 Self(unsafe { _mm_and_ps(self.0, rhs.0) }) 149 } 150 } 151 152 impl BitAndAssign for BVec3A { 153 #[inline] bitand_assign(&mut self, rhs: Self)154 fn bitand_assign(&mut self, rhs: Self) { 155 *self = self.bitand(rhs); 156 } 157 } 158 159 impl BitOr for BVec3A { 160 type Output = Self; 161 #[inline] bitor(self, rhs: Self) -> Self162 fn bitor(self, rhs: Self) -> Self { 163 Self(unsafe { _mm_or_ps(self.0, rhs.0) }) 164 } 165 } 166 167 impl BitOrAssign for BVec3A { 168 #[inline] bitor_assign(&mut self, rhs: Self)169 fn bitor_assign(&mut self, rhs: Self) { 170 *self = self.bitor(rhs); 171 } 172 } 173 174 impl BitXor for BVec3A { 175 type Output = Self; 176 #[inline] bitxor(self, rhs: Self) -> Self177 fn bitxor(self, rhs: Self) -> Self { 178 Self(unsafe { _mm_xor_ps(self.0, rhs.0) }) 179 } 180 } 181 182 impl BitXorAssign for BVec3A { 183 #[inline] bitxor_assign(&mut self, rhs: Self)184 fn bitxor_assign(&mut self, rhs: Self) { 185 *self = self.bitxor(rhs); 186 } 187 } 188 189 impl Not for BVec3A { 190 type Output = Self; 191 #[inline] not(self) -> Self192 fn not(self) -> Self { 193 Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) }) 194 } 195 } 196 197 impl From<BVec3A> for __m128 { 198 #[inline] from(t: BVec3A) -> Self199 fn from(t: BVec3A) -> Self { 200 t.0 201 } 202 } 203 204 #[cfg(not(target_arch = "spirv"))] 205 impl fmt::Debug for BVec3A { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 207 let arr = self.into_u32_array(); 208 write!( 209 f, 210 "{}({:#x}, {:#x}, {:#x})", 211 stringify!(BVec3A), 212 arr[0], 213 arr[1], 214 arr[2] 215 ) 216 } 217 } 218 219 #[cfg(not(target_arch = "spirv"))] 220 impl fmt::Display for BVec3A { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 222 let arr = self.into_bool_array(); 223 write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2]) 224 } 225 } 226 227 impl From<BVec3A> for [bool; 3] { 228 #[inline] from(mask: BVec3A) -> Self229 fn from(mask: BVec3A) -> Self { 230 mask.into_bool_array() 231 } 232 } 233 234 impl From<BVec3A> for [u32; 3] { 235 #[inline] from(mask: BVec3A) -> Self236 fn from(mask: BVec3A) -> Self { 237 mask.into_u32_array() 238 } 239 } 240