use std::{
any::{type_name, TypeId},
fmt::Debug,
mem::{align_of, size_of, transmute, transmute_copy, MaybeUninit},
ptr::copy_nonoverlapping,
};
use bytemuck::{AnyBitPattern, NoUninit, Pod, Zeroable};
use crate::generic::{VertexBinding, VertexFormat, Zero};
pub trait DeviceRepr: Sized + 'static {
type Repr: bytemuck::Pod + Debug;
type ArrayRepr: bytemuck::Pod + Debug;
fn as_repr(&self) -> Self::Repr;
#[inline(always)]
#[cold]
fn make_array_repr(&self) -> Self::ArrayRepr {
unimplemented!("<{} as DeviceRepr>::make_array_repr must be implemented if size of `ArrayRepr` is not equal to size of `Repr`", type_name::<Self>());
}
#[inline(always)]
fn as_array_repr(&self) -> Self::ArrayRepr {
if size_of::<Self::Repr>() == size_of::<Self::ArrayRepr>() {
unsafe { bytemuck::cast(self.as_repr()) }
}
self.make_array_repr()
}
#[inline(always)]
fn as_bytes(repr: &Self::Repr) -> &[u8] {
bytemuck::bytes_of(repr)
}
#[inline(always)]
fn as_array_bytes(repr: &[Self::ArrayRepr]) -> &[u8] {
bytemuck::cast_slice(repr)
}
const ALIGN: usize;
const SIZE: usize = size_of::<Self::Repr>();
const ARRAY_SIZE: usize = size_of::<Self::ArrayRepr>();
}
pub trait AutoDeviceRepr: bytemuck::Pod + DeviceRepr<Repr = Self, ArrayRepr = Self> {}
impl<T> AutoDeviceRepr for T where T: bytemuck::Pod + DeviceRepr<Repr = Self, ArrayRepr = Self> {}
#[inline]
fn array_as_repr_slow<T: DeviceRepr, const N: usize>(array: &[T; N]) -> [T::ArrayRepr; N] {
let mut repr: MaybeUninit<[T::ArrayRepr; N]> = MaybeUninit::uninit();
let ptr = repr.as_mut_ptr().cast::<T::ArrayRepr>();
for idx in 0..N {
unsafe {
ptr.add(idx).write(array[idx].as_array_repr());
}
}
unsafe { repr.assume_init() }
}
impl<T, const N: usize> DeviceRepr for [T; N]
where
T: DeviceRepr,
{
type Repr = [T::ArrayRepr; N];
type ArrayRepr = [T::ArrayRepr; N];
#[inline(always)]
fn as_repr(&self) -> [T::ArrayRepr; N] {
if TypeId::of::<Self>() == TypeId::of::<T::ArrayRepr>() {
return unsafe { transmute_copy(self) };
}
if TypeId::of::<Self>() == TypeId::of::<T::Repr>()
&& size_of::<T::Repr>() == size_of::<T::ArrayRepr>()
{
return unsafe { transmute_copy(self) };
}
array_as_repr_slow(self)
}
#[inline(always)]
fn as_array_repr(&self) -> [T::ArrayRepr; N] {
self.as_repr()
}
const ALIGN: usize = T::ALIGN;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ScalarType {
Bool,
Sint8,
Uint8,
Sint16,
Uint16,
Sint32,
Uint32,
Sint64,
Uint64,
Float16,
Float32,
Float64,
}
impl ScalarType {
#[inline(always)]
pub const fn size(&self) -> usize {
match self {
ScalarType::Bool => 1,
ScalarType::Sint8 => 1,
ScalarType::Uint8 => 1,
ScalarType::Sint16 => 2,
ScalarType::Uint16 => 2,
ScalarType::Sint32 => 4,
ScalarType::Uint32 => 4,
ScalarType::Sint64 => 8,
ScalarType::Uint64 => 8,
ScalarType::Float16 => 2,
ScalarType::Float32 => 4,
ScalarType::Float64 => 8,
}
}
}
pub trait Scalar: crate::private::Sealed + bytemuck::NoUninit + Sized + Debug + 'static {
const TYPE: ScalarType;
type ScalarRepr: bytemuck::Pod + Debug;
#[inline(always)]
fn as_scalar_repr(&self) -> Self::ScalarRepr {
assert_eq!(align_of::<Self>(), align_of::<Self::ScalarRepr>());
assert_eq!(size_of::<Self>(), size_of::<Self::ScalarRepr>());
bytemuck::cast(*self)
}
}
pub trait VertexScalar: Scalar {}
const fn vertex_format<T: VertexScalar>(size: VectorSize) -> VertexFormat {
match (T::TYPE, size) {
(ScalarType::Sint64 | ScalarType::Uint64 | ScalarType::Float64, _) => {
panic!("64-bit scalars do not implement VertexScalar")
}
(ScalarType::Bool, VectorSize::One) => VertexFormat::Uint8,
(ScalarType::Sint8, VectorSize::One) => VertexFormat::Sint32,
(ScalarType::Uint8, VectorSize::One) => VertexFormat::Uint32,
(ScalarType::Sint16, VectorSize::One) => VertexFormat::Sint32,
(ScalarType::Uint16, VectorSize::One) => VertexFormat::Uint32,
(ScalarType::Float16, VectorSize::One) => VertexFormat::Float32,
(ScalarType::Sint32, VectorSize::One) => VertexFormat::Sint32,
(ScalarType::Uint32, VectorSize::One) => VertexFormat::Uint32,
(ScalarType::Float32, VectorSize::One) => VertexFormat::Float32,
(ScalarType::Bool, VectorSize::Two) => VertexFormat::Uint8x2,
(ScalarType::Sint8, VectorSize::Two) => VertexFormat::Sint8x2,
(ScalarType::Uint8, VectorSize::Two) => VertexFormat::Uint8x2,
(ScalarType::Sint16, VectorSize::Two) => VertexFormat::Sint16x2,
(ScalarType::Uint16, VectorSize::Two) => VertexFormat::Uint16x2,
(ScalarType::Float16, VectorSize::Two) => VertexFormat::Float16x2,
(ScalarType::Sint32, VectorSize::Two) => VertexFormat::Sint32x2,
(ScalarType::Uint32, VectorSize::Two) => VertexFormat::Uint32x2,
(ScalarType::Float32, VectorSize::Two) => VertexFormat::Float32x2,
(ScalarType::Bool, VectorSize::Three) => VertexFormat::Uint8x3,
(ScalarType::Sint8, VectorSize::Three) => VertexFormat::Sint8x3,
(ScalarType::Uint8, VectorSize::Three) => VertexFormat::Uint8x3,
(ScalarType::Sint16, VectorSize::Three) => VertexFormat::Sint16x3,
(ScalarType::Uint16, VectorSize::Three) => VertexFormat::Uint16x3,
(ScalarType::Float16, VectorSize::Three) => VertexFormat::Float16x3,
(ScalarType::Sint32, VectorSize::Three) => VertexFormat::Sint32x3,
(ScalarType::Uint32, VectorSize::Three) => VertexFormat::Uint32x3,
(ScalarType::Float32, VectorSize::Three) => VertexFormat::Float32x3,
(ScalarType::Bool, VectorSize::Four) => VertexFormat::Uint8x4,
(ScalarType::Sint8, VectorSize::Four) => VertexFormat::Sint8x4,
(ScalarType::Uint8, VectorSize::Four) => VertexFormat::Uint8x4,
(ScalarType::Sint16, VectorSize::Four) => VertexFormat::Sint16x4,
(ScalarType::Uint16, VectorSize::Four) => VertexFormat::Uint16x4,
(ScalarType::Float16, VectorSize::Four) => VertexFormat::Float16x4,
(ScalarType::Sint32, VectorSize::Four) => VertexFormat::Sint32x4,
(ScalarType::Uint32, VectorSize::Four) => VertexFormat::Uint32x4,
(ScalarType::Float32, VectorSize::Four) => VertexFormat::Float32x4,
}
}
impl<T> DeviceRepr for T
where
T: Scalar,
{
type Repr = T::ScalarRepr;
type ArrayRepr = T::ScalarRepr;
#[inline(always)]
fn as_repr(&self) -> Self::Repr {
self.as_scalar_repr()
}
#[inline(always)]
fn as_array_repr(&self) -> Self::ArrayRepr {
self.as_scalar_repr()
}
const ALIGN: usize = align_of::<Self>();
}
impl crate::private::Sealed for bool {}
impl Scalar for bool {
const TYPE: ScalarType = ScalarType::Bool;
type ScalarRepr = u8;
}
impl crate::private::Sealed for i8 {}
impl Scalar for i8 {
const TYPE: ScalarType = ScalarType::Sint8;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
impl VertexScalar for i8 {}
impl crate::private::Sealed for u8 {}
impl Scalar for u8 {
const TYPE: ScalarType = ScalarType::Uint8;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
impl VertexScalar for u8 {}
impl crate::private::Sealed for i16 {}
impl Scalar for i16 {
const TYPE: ScalarType = ScalarType::Sint16;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
impl VertexScalar for i16 {}
impl crate::private::Sealed for u16 {}
impl Scalar for u16 {
const TYPE: ScalarType = ScalarType::Uint16;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
impl VertexScalar for u16 {}
impl crate::private::Sealed for i32 {}
impl Scalar for i32 {
const TYPE: ScalarType = ScalarType::Sint32;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
impl VertexScalar for i32 {}
impl crate::private::Sealed for u32 {}
impl Scalar for u32 {
const TYPE: ScalarType = ScalarType::Uint32;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
impl VertexScalar for u32 {}
impl crate::private::Sealed for i64 {}
impl Scalar for i64 {
const TYPE: ScalarType = ScalarType::Sint64;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
impl crate::private::Sealed for u64 {}
impl Scalar for u64 {
const TYPE: ScalarType = ScalarType::Uint64;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
impl crate::private::Sealed for f32 {}
impl Scalar for f32 {
const TYPE: ScalarType = ScalarType::Float32;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
impl VertexScalar for f32 {}
impl crate::private::Sealed for f64 {}
impl Scalar for f64 {
const TYPE: ScalarType = ScalarType::Float64;
type ScalarRepr = Self;
#[inline(always)]
fn as_scalar_repr(&self) -> Self {
*self
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum VectorSize {
One = 1,
Two = 2,
Three = 3,
Four = 4,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct DataType {
pub scalar: ScalarType,
pub columns: VectorSize,
pub rows: VectorSize,
}
pub trait VertexAttributes: crate::private::Sealed + 'static {
const FORMAT: VertexFormat;
const COUNT: VectorSize;
}
impl<T> VertexAttributes for T
where
T: VertexScalar,
{
const FORMAT: VertexFormat = vertex_format::<T>(VectorSize::One);
const COUNT: VectorSize = VectorSize::One;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
pub struct vec<T, const N: usize>(pub [T; N]);
unsafe impl<T, const N: usize> Zeroable for vec<T, N> where T: Zeroable {}
unsafe impl<T, const N: usize> Pod for vec<T, N> where T: Pod {}
impl<T, const N: usize> From<vec<T, N>> for [T; N] {
#[inline(always)]
fn from(v: vec<T, N>) -> Self {
v.0
}
}
impl<T, const N: usize> From<[T; N]> for vec<T, N> {
#[inline(always)]
fn from(v: [T; N]) -> Self {
vec(v)
}
}
impl<T, const N: usize> From<&[T; N]> for vec<T, N>
where
T: Copy,
{
#[inline(always)]
fn from(v: &[T; N]) -> Self {
vec(*v)
}
}
impl<T, const N: usize> Zero for vec<T, N>
where
T: Zero,
{
const ZERO: Self = vec([T::ZERO; N]);
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
pub struct mat<T, const N: usize, const M: usize>(pub [vec<T, M>; N]);
impl<T, const N: usize, const M: usize> Zero for mat<T, N, M>
where
T: Zero,
{
const ZERO: Self = mat([const { vec([T::ZERO; M]) }; N]);
}
unsafe impl<T, const N: usize, const M: usize> Zeroable for mat<T, N, M> where T: Zeroable {}
unsafe impl<T, const N: usize, const M: usize> Pod for mat<T, N, M> where T: Pod {}
impl<T, const N: usize, const M: usize> From<mat<T, N, M>> for [[T; M]; N] {
#[inline(always)]
fn from(m: mat<T, N, M>) -> Self {
m.0.map(From::from)
}
}
impl<T, const N: usize, const M: usize> From<[[T; M]; N]> for mat<T, N, M> {
#[inline(always)]
fn from(m: [[T; M]; N]) -> Self {
mat(m.map(From::from))
}
}
impl<T, const N: usize, const M: usize> From<&[[T; M]; N]> for mat<T, N, M>
where
T: Copy,
{
#[inline(always)]
fn from(m: &[[T; M]; N]) -> Self {
mat(m.map(From::from))
}
}
#[allow(non_camel_case_types)]
pub type vec2<T = f32> = vec<T, 2>;
#[inline(always)]
pub fn vec2<T>(x: T, y: T) -> vec2<T> {
vec([x, y])
}
#[allow(non_camel_case_types)]
pub type vec3<T = f32> = vec<T, 3>;
#[inline(always)]
pub fn vec3<T>(x: T, y: T, z: T) -> vec3<T> {
vec([x, y, z])
}
#[allow(non_camel_case_types)]
pub type vec4<T = f32> = vec<T, 4>;
#[inline(always)]
pub fn vec4<T>(x: T, y: T, z: T, w: T) -> vec4<T> {
vec([x, y, z, w])
}
#[allow(non_camel_case_types)]
pub type mat2<T = f32> = mat<T, 2, 2>;
#[inline(always)]
pub fn mat2<T>(x: vec2<T>, y: vec2<T>) -> mat2<T> {
mat([x, y])
}
#[allow(non_camel_case_types)]
pub type mat3<T = f32> = mat<T, 3, 3>;
#[inline(always)]
pub fn mat3<T>(x: vec3<T>, y: vec3<T>, z: vec3<T>) -> mat3<T> {
mat([x, y, z])
}
#[allow(non_camel_case_types)]
pub type mat4<T = f32> = mat<T, 4, 4>;
#[inline(always)]
pub fn mat4<T>(x: vec4<T>, y: vec4<T>, z: vec4<T>, w: vec4<T>) -> mat4<T> {
mat([x, y, z, w])
}
#[allow(non_camel_case_types)]
pub type mat2x2<T = f32> = mat<T, 2, 2>;
#[inline(always)]
pub fn mat2x2<T>(x: vec2<T>, y: vec2<T>) -> mat2x2<T> {
mat([x, y])
}
#[allow(non_camel_case_types)]
pub type mat2x3<T = f32> = mat<T, 2, 3>;
#[inline(always)]
pub fn mat2x3<T>(x: vec3<T>, y: vec3<T>) -> mat2x3<T> {
mat([x, y])
}
#[allow(non_camel_case_types)]
pub type mat2x4<T = f32> = mat<T, 2, 4>;
#[inline(always)]
pub fn mat2x4<T>(x: vec4<T>, y: vec4<T>) -> mat2x4<T> {
mat([x, y])
}
#[allow(non_camel_case_types)]
pub type mat3x2<T = f32> = mat<T, 3, 2>;
#[inline(always)]
pub fn mat3x2<T>(x: vec2<T>, y: vec2<T>, z: vec2<T>) -> mat3x2<T> {
mat([x, y, z])
}
#[allow(non_camel_case_types)]
pub type mat3x3<T = f32> = mat<T, 3, 3>;
#[inline(always)]
pub fn mat3x3<T>(x: vec3<T>, y: vec3<T>, z: vec3<T>) -> mat3x3<T> {
mat([x, y, z])
}
#[allow(non_camel_case_types)]
pub type mat3x4<T = f32> = mat<T, 3, 4>;
#[inline(always)]
pub fn mat3x4<T>(x: vec4<T>, y: vec4<T>, z: vec4<T>) -> mat3x4<T> {
mat([x, y, z])
}
#[allow(non_camel_case_types)]
pub type mat4x2<T = f32> = mat<T, 4, 2>;
#[inline(always)]
pub fn mat4x2<T>(x: vec2<T>, y: vec2<T>, z: vec2<T>, w: vec2<T>) -> mat4x2<T> {
mat([x, y, z, w])
}
#[allow(non_camel_case_types)]
pub type mat4x3<T = f32> = mat<T, 4, 3>;
#[inline(always)]
pub fn mat4x3<T>(x: vec3<T>, y: vec3<T>, z: vec3<T>, w: vec3<T>) -> mat4x3<T> {
mat([x, y, z, w])
}
#[allow(non_camel_case_types)]
pub type mat4x4<T = f32> = mat<T, 4, 4>;
#[inline(always)]
pub fn mat4x4<T>(x: vec4<T>, y: vec4<T>, z: vec4<T>, w: vec4<T>) -> mat4x4<T> {
mat([x, y, z, w])
}
impl<T> crate::private::Sealed for vec<T, 1> where T: Scalar {}
impl<T> crate::private::Sealed for vec<T, 2> where T: Scalar {}
impl<T> crate::private::Sealed for vec<T, 3> where T: Scalar {}
impl<T> crate::private::Sealed for vec<T, 4> where T: Scalar {}
impl<T, const N: usize> crate::private::Sealed for mat<T, 1, N> where
vec<T, N>: crate::private::Sealed
{
}
impl<T, const N: usize> crate::private::Sealed for mat<T, 2, N> where
vec<T, N>: crate::private::Sealed
{
}
impl<T, const N: usize> crate::private::Sealed for mat<T, 3, N> where
vec<T, N>: crate::private::Sealed
{
}
impl<T, const N: usize> crate::private::Sealed for mat<T, 4, N> where
vec<T, N>: crate::private::Sealed
{
}
impl<T> VertexAttributes for vec2<T>
where
T: VertexScalar,
{
const FORMAT: VertexFormat = vertex_format::<T>(VectorSize::Two);
const COUNT: VectorSize = VectorSize::One;
}
impl<T> VertexAttributes for vec3<T>
where
T: VertexScalar,
{
const FORMAT: VertexFormat = vertex_format::<T>(VectorSize::Three);
const COUNT: VectorSize = VectorSize::One;
}
impl<T> VertexAttributes for vec4<T>
where
T: VertexScalar,
{
const FORMAT: VertexFormat = vertex_format::<T>(VectorSize::Four);
const COUNT: VectorSize = VectorSize::One;
}
impl<T, const M: usize> VertexAttributes for mat<T, 2, M>
where
vec<T, M>: VertexAttributes,
{
const FORMAT: VertexFormat = <vec<T, M> as VertexAttributes>::FORMAT;
const COUNT: VectorSize = VectorSize::Two;
}
impl<T, const M: usize> VertexAttributes for mat<T, 3, M>
where
vec<T, M>: VertexAttributes,
{
const FORMAT: VertexFormat = <vec<T, M> as VertexAttributes>::FORMAT;
const COUNT: VectorSize = VectorSize::Three;
}
impl<T, const M: usize> VertexAttributes for mat<T, 4, M>
where
vec<T, M>: VertexAttributes,
{
const FORMAT: VertexFormat = <vec<T, M> as VertexAttributes>::FORMAT;
const COUNT: VectorSize = VectorSize::Four;
}
impl<T> DeviceRepr for vec2<T>
where
T: Scalar,
{
type Repr = vec2<T::ScalarRepr>;
type ArrayRepr = vec2<T::ScalarRepr>;
#[inline(always)]
fn as_repr(&self) -> Self::Repr {
vec(self.0.as_repr())
}
const ALIGN: usize = size_of::<vec2<T::ScalarRepr>>();
}
impl<T> DeviceRepr for vec3<T>
where
T: Scalar,
{
type Repr = vec3<T::ScalarRepr>;
type ArrayRepr = vec4<T::ScalarRepr>;
#[inline(always)]
fn as_repr(&self) -> Self::Repr {
vec(self.0.as_repr())
}
#[inline(always)]
fn make_array_repr(&self) -> vec4<T::ScalarRepr> {
let [a, b, c] = self.0.as_repr();
vec([a, b, c, Zeroable::zeroed()])
}
const ALIGN: usize = size_of::<vec4<T::ScalarRepr>>();
}
impl<T> DeviceRepr for vec4<T>
where
T: Scalar,
{
type Repr = vec4<T::ScalarRepr>;
type ArrayRepr = vec4<T::ScalarRepr>;
#[inline(always)]
fn as_repr(&self) -> Self::Repr {
vec(self.0.as_repr())
}
const ALIGN: usize = size_of::<vec4<T::ScalarRepr>>();
}
impl<T, const N: usize> DeviceRepr for mat<T, N, 2>
where
T: Scalar,
{
type Repr = mat<T::ScalarRepr, N, 2>;
type ArrayRepr = mat<T::ScalarRepr, N, 2>;
#[inline(always)]
fn as_repr(&self) -> Self::Repr {
mat(self.0.as_repr())
}
const ALIGN: usize = size_of::<vec2<T::ScalarRepr>>();
}
impl<T, const N: usize> DeviceRepr for mat<T, N, 3>
where
T: Scalar,
{
type Repr = mat<T::ScalarRepr, N, 4>;
type ArrayRepr = mat<T::ScalarRepr, N, 4>;
#[inline(always)]
fn as_repr(&self) -> Self::Repr {
mat(self.0.as_repr())
}
const ALIGN: usize = size_of::<vec4<T::ScalarRepr>>();
}
impl<T, const N: usize> DeviceRepr for mat<T, N, 4>
where
T: Scalar,
{
type Repr = mat<T::ScalarRepr, N, 4>;
type ArrayRepr = mat<T::ScalarRepr, N, 4>;
#[inline(always)]
fn as_repr(&self) -> Self::Repr {
mat(self.0.as_repr())
}
const ALIGN: usize = size_of::<vec4<T::ScalarRepr>>();
}
#[allow(non_camel_case_types)]
pub type bvec2 = vec2<bool>;
#[allow(non_camel_case_types)]
pub type bvec3 = vec3<bool>;
#[allow(non_camel_case_types)]
pub type bvec4 = vec4<bool>;
#[allow(non_camel_case_types)]
pub type bmat2 = mat2<bool>;
#[allow(non_camel_case_types)]
pub type bmat3 = mat3<bool>;
#[allow(non_camel_case_types)]
pub type bmat4 = mat4<bool>;
#[allow(non_camel_case_types)]
pub type bmat2x2 = mat2x2<bool>;
#[allow(non_camel_case_types)]
pub type bmat2x3 = mat2x3<bool>;
#[allow(non_camel_case_types)]
pub type bmat2x4 = mat2x4<bool>;
#[allow(non_camel_case_types)]
pub type bmat3x2 = mat3x2<bool>;
#[allow(non_camel_case_types)]
pub type bmat3x3 = mat3x3<bool>;
#[allow(non_camel_case_types)]
pub type bmat3x4 = mat3x4<bool>;
#[allow(non_camel_case_types)]
pub type bmat4x2 = mat4x2<bool>;
#[allow(non_camel_case_types)]
pub type bmat4x3 = mat4x3<bool>;
#[allow(non_camel_case_types)]
pub type bmat4x4 = mat4x4<bool>;
#[allow(non_camel_case_types)]
pub type ivec2 = vec2<i32>;
#[allow(non_camel_case_types)]
pub type ivec3 = vec3<i32>;
#[allow(non_camel_case_types)]
pub type ivec4 = vec4<i32>;
#[allow(non_camel_case_types)]
pub type imat2 = mat2<i32>;
#[allow(non_camel_case_types)]
pub type imat3 = mat3<i32>;
#[allow(non_camel_case_types)]
pub type imat4 = mat4<i32>;
#[allow(non_camel_case_types)]
pub type imat2x2 = mat2x2<i32>;
#[allow(non_camel_case_types)]
pub type imat2x3 = mat2x3<i32>;
#[allow(non_camel_case_types)]
pub type imat2x4 = mat2x4<i32>;
#[allow(non_camel_case_types)]
pub type imat3x2 = mat3x2<i32>;
#[allow(non_camel_case_types)]
pub type imat3x3 = mat3x3<i32>;
#[allow(non_camel_case_types)]
pub type imat3x4 = mat3x4<i32>;
#[allow(non_camel_case_types)]
pub type imat4x2 = mat4x2<i32>;
#[allow(non_camel_case_types)]
pub type imat4x3 = mat4x3<i32>;
#[allow(non_camel_case_types)]
pub type imat4x4 = mat4x4<i32>;
#[allow(non_camel_case_types)]
pub type uvec2 = vec2<u32>;
#[allow(non_camel_case_types)]
pub type uvec3 = vec3<u32>;
#[allow(non_camel_case_types)]
pub type uvec4 = vec4<u32>;
#[allow(non_camel_case_types)]
pub type umat2 = mat2<u32>;
#[allow(non_camel_case_types)]
pub type umat3 = mat3<u32>;
#[allow(non_camel_case_types)]
pub type umat4 = mat4<u32>;
#[allow(non_camel_case_types)]
pub type umat2x2 = mat2x2<u32>;
#[allow(non_camel_case_types)]
pub type umat2x3 = mat2x3<u32>;
#[allow(non_camel_case_types)]
pub type umat2x4 = mat2x4<u32>;
#[allow(non_camel_case_types)]
pub type umat3x2 = mat3x2<u32>;
#[allow(non_camel_case_types)]
pub type umat3x3 = mat3x3<u32>;
#[allow(non_camel_case_types)]
pub type umat3x4 = mat3x4<u32>;
#[allow(non_camel_case_types)]
pub type umat4x2 = mat4x2<u32>;
#[allow(non_camel_case_types)]
pub type umat4x3 = mat4x3<u32>;
#[allow(non_camel_case_types)]
pub type umat4x4 = mat4x4<u32>;
#[allow(non_camel_case_types)]
pub type dvec2 = vec2<f64>;
#[allow(non_camel_case_types)]
pub type dvec3 = vec3<f64>;
#[allow(non_camel_case_types)]
pub type dvec4 = vec4<f64>;
#[allow(non_camel_case_types)]
pub type dmat2 = mat2<f64>;
#[allow(non_camel_case_types)]
pub type dmat3 = mat3<f64>;
#[allow(non_camel_case_types)]
pub type dmat4 = mat4<f64>;
#[allow(non_camel_case_types)]
pub type dmat2x2 = mat2x2<f64>;
#[allow(non_camel_case_types)]
pub type dmat2x3 = mat2x3<f64>;
#[allow(non_camel_case_types)]
pub type dmat2x4 = mat2x4<f64>;
#[allow(non_camel_case_types)]
pub type dmat3x2 = mat3x2<f64>;
#[allow(non_camel_case_types)]
pub type dmat3x3 = mat3x3<f64>;
#[allow(non_camel_case_types)]
pub type dmat3x4 = mat3x4<f64>;
#[allow(non_camel_case_types)]
pub type dmat4x2 = mat4x2<f64>;
#[allow(non_camel_case_types)]
pub type dmat4x3 = mat4x3<f64>;
#[allow(non_camel_case_types)]
pub type dmat4x4 = mat4x4<f64>;