#![allow(missing_docs)]
use super::shade::BaseType;
pub type Count = u8;
pub type Offset = u32;
pub type Stride = u8;
pub type InstanceRate = u8;
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
#[repr(u8)]
pub enum SignFlag {
Signed,
Unsigned,
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
#[repr(u8)]
pub enum IntSubType {
Raw, Normalized, AsFloat, }
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
#[repr(u8)]
pub enum IntSize {
U8,
U16,
U32,
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
#[repr(u8)]
pub enum FloatSubType {
Default, Precision, }
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
#[repr(u8)]
pub enum FloatSize {
F16,
F32,
F64,
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub enum Type {
Int(IntSubType, IntSize, SignFlag),
Float(FloatSubType, FloatSize),
Special,
}
impl Type {
pub fn is_compatible(&self, bt: BaseType) -> Result<(), ()> {
match (*self, bt) {
(Type::Int(IntSubType::Raw, _, _), BaseType::I32) => Ok(()),
(Type::Int(IntSubType::Raw, _, SignFlag::Unsigned), BaseType::U32) => Ok(()),
(Type::Int(IntSubType::Raw, _, _), _) => Err(()),
(Type::Int(_, _, _), BaseType::F32) => Ok(()),
(Type::Int(_, _, _), _) => Err(()),
(Type::Float(_, _), BaseType::F32) => Ok(()),
(Type::Float(FloatSubType::Precision, FloatSize::F64), BaseType::F64) => Ok(()),
(Type::Float(_, _), _) => Err(()),
(_, BaseType::F64) => Err(()),
(_, BaseType::Bool) => Err(()),
_ => Err(()),
}
}
pub fn get_size(&self) -> u8 {
match *self {
Type::Int(_, IntSize::U8, _) => 1,
Type::Int(_, IntSize::U16, _) => 2,
Type::Int(_, IntSize::U32, _) => 4,
Type::Float(_, FloatSize::F16) => 2,
Type::Float(_, FloatSize::F32) => 4,
Type::Float(_, FloatSize::F64) => 8,
Type::Special => 0,
}
}
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub struct Format {
pub elem_count: Count,
pub elem_type: Type,
pub offset: Offset,
pub stride: Stride,
pub instance_rate: InstanceRate,
}
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub struct FixedPoint<T>(pub T);
impl<T: Copy> FixedPoint<T> {
pub fn cast2(a: [T; 2]) -> [FixedPoint<T>; 2] {
[FixedPoint(a[0]), FixedPoint(a[1])]
}
pub fn cast3(a: [T; 3]) -> [FixedPoint<T>; 3] {
[FixedPoint(a[0]), FixedPoint(a[1]), FixedPoint(a[2])]
}
pub fn cast4(a: [T; 4]) -> [FixedPoint<T>; 4] {
[FixedPoint(a[0]), FixedPoint(a[1]),
FixedPoint(a[2]), FixedPoint(a[3])]
}
}
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub struct Floater<T>(pub T);
impl<T: Copy> Floater<T> {
pub fn cast2(a: [T; 2]) -> [Floater<T>; 2] {
[Floater(a[0]), Floater(a[1])]
}
pub fn cast3(a: [T; 3]) -> [Floater<T>; 3] {
[Floater(a[0]), Floater(a[1]), Floater(a[2])]
}
pub fn cast4(a: [T; 4]) -> [Floater<T>; 4] {
[Floater(a[0]), Floater(a[1]),
Floater(a[2]), Floater(a[3])]
}
}
pub mod format {
use super::{Count, FixedPoint, Floater, Type};
use super::Type::*;
use super::FloatSize::*;
use super::FloatSubType::*;
use super::IntSize::*;
use super::IntSubType::*;
use super::SignFlag::*;
pub trait ToFormat {
fn describe() -> (Count, Type);
}
pub trait ToType {
fn describe() -> Type;
}
impl<T: ToType> ToFormat for T {
fn describe() -> (Count, Type) {
(1, T::describe())
}
}
impl<T: ToType> ToFormat for [T; 2] {
fn describe() -> (Count, Type) {
(2, T::describe())
}
}
impl<T: ToType> ToFormat for [T; 3] {
fn describe() -> (Count, Type) {
(3, T::describe())
}
}
impl<T: ToType> ToFormat for [T; 4] {
fn describe() -> (Count, Type) {
(4, T::describe())
}
}
impl ToType for f32 {
fn describe() -> Type { Float(Default, F32) }
}
impl ToType for f64 {
fn describe() -> Type { Float(Precision, F64) }
}
impl ToType for u8 {
fn describe() -> Type { Int(Raw, U8, Unsigned) }
}
impl ToType for u16 {
fn describe() -> Type { Int(Raw, U16, Unsigned) }
}
impl ToType for u32 {
fn describe() -> Type { Int(Raw, U32, Unsigned) }
}
impl ToType for i8 {
fn describe() -> Type { Int(Raw, U8, Signed) }
}
impl ToType for i16 {
fn describe() -> Type { Int(Raw, U16, Signed) }
}
impl ToType for i32 {
fn describe() -> Type { Int(Raw, U32, Signed) }
}
impl ToType for FixedPoint<u8> {
fn describe() -> Type { Int(Normalized, U8, Unsigned) }
}
impl ToType for FixedPoint<u16> {
fn describe() -> Type { Int(Normalized, U16, Unsigned) }
}
impl ToType for FixedPoint<u32> {
fn describe() -> Type { Int(Normalized, U32, Unsigned) }
}
impl ToType for FixedPoint<i8> {
fn describe() -> Type { Int(Normalized, U8, Signed) }
}
impl ToType for FixedPoint<i16> {
fn describe() -> Type { Int(Normalized, U16, Signed) }
}
impl ToType for FixedPoint<i32> {
fn describe() -> Type { Int(Normalized, U32, Signed) }
}
impl ToType for Floater<u8> {
fn describe() -> Type { Int(AsFloat, U8, Unsigned) }
}
impl ToType for Floater<u16> {
fn describe() -> Type { Int(AsFloat, U16, Unsigned) }
}
impl ToType for Floater<u32> {
fn describe() -> Type { Int(AsFloat, U32, Unsigned) }
}
impl ToType for Floater<i8> {
fn describe() -> Type { Int(AsFloat, U8, Signed) }
}
impl ToType for Floater<i16> {
fn describe() -> Type { Int(AsFloat, U16, Signed) }
}
impl ToType for Floater<i32> {
fn describe() -> Type { Int(AsFloat, U32, Signed) }
}
}