1use memory::Pod;
24
25macro_rules! impl_channel_type {
26 { $($name:ident = $shader_type:ident [ $($imp_trait:ident),* ] ,)* } => {
27 #[allow(missing_docs)]
30 #[repr(u8)]
31 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
32 #[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
33 pub enum ChannelType {
34 $( $name, )*
35 }
36 $(
37 #[allow(missing_docs)]
38 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
39 #[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
40 pub enum $name {}
41 impl ChannelTyped for $name {
42 type ShaderType = $shader_type;
43 fn get_channel_type() -> ChannelType {
44 ChannelType::$name
45 }
46 }
47 $(
48 impl $imp_trait for $name {}
49 )*
50 )*
51 }
52}
53
54impl_channel_type! {
55 Int = i32 [TextureChannel, RenderChannel],
56 Uint = u32 [TextureChannel, RenderChannel],
57 Inorm = f32 [TextureChannel, RenderChannel, BlendChannel],
58 Unorm = f32 [TextureChannel, RenderChannel, BlendChannel],
59 Float = f32 [TextureChannel, RenderChannel, BlendChannel],
60 Srgb = f32 [TextureChannel, RenderChannel, BlendChannel],
61}
62
63macro_rules! impl_formats {
64 { $($name:ident : $container:ident < $($channel:ident),* > = $data_type:ty {$alpha_bits:expr} [ $($imp_trait:ident),* ], doc = $doc:expr ,)* } => {
65 #[repr(u8)]
70 #[allow(missing_docs, non_camel_case_types)]
71 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
72 #[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
73 pub enum SurfaceType {
74 $( #[doc = $doc] $name, )*
75 }
76 impl SurfaceType {
77 pub fn get_total_bits(&self) -> u8 {
79 use std::mem::size_of;
80 match *self {
81 $( SurfaceType::$name => (size_of::<$data_type>() * 8) as u8, )*
82 }
83 }
84 pub fn get_alpha_stencil_bits(&self) -> u8 {
86 match *self {
87 $( SurfaceType::$name => $alpha_bits, )*
88 }
89 }
90 }
91 $(
92 #[allow(missing_docs, non_camel_case_types)]
93 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
94 #[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
95 #[doc = $doc]
96 pub enum $name {}
97 impl SurfaceTyped for $name {
98 type DataType = $data_type;
99 fn get_surface_type() -> SurfaceType {
100 SurfaceType::$name
101 }
102 }
103 $(
104 impl $imp_trait for $name {}
105 )*
106 $(
107 impl Formatted for ($name, $channel) {
108 type Surface = $name;
109 type Channel = $channel;
110 type View = $container< <$channel as ChannelTyped>::ShaderType >;
111 }
112 )*
113 )*
114 }
115}
116
117
118impl_formats! {
119 R4_G4 : Vec2<Unorm> = u8 {0} [TextureSurface, RenderSurface], doc = "",
120 R4_G4_B4_A4 : Vec4<Unorm> = u16 {4} [TextureSurface, RenderSurface], doc = "",
121 R5_G5_B5_A1 : Vec4<Unorm> = u16 {1} [TextureSurface, RenderSurface], doc = "",
122 R5_G6_B5 : Vec3<Unorm> = u16 {0} [TextureSurface, RenderSurface], doc = "",
123 R8 : Vec1<Int, Uint, Inorm, Unorm> = u8 {0}
124 [BufferSurface, TextureSurface, RenderSurface], doc = "",
125 R8_G8 : Vec2<Int, Uint, Inorm, Unorm> = [u8; 2] {0}
126 [BufferSurface, TextureSurface, RenderSurface], doc = "",
127 R8_G8_B8_A8 : Vec4<Int, Uint, Inorm, Unorm, Srgb> = [u8; 4] {8}
128 [BufferSurface, TextureSurface, RenderSurface], doc = "",
129 R10_G10_B10_A2 : Vec4<Uint, Unorm> = u32 {2}
130 [BufferSurface, TextureSurface, RenderSurface], doc = "",
131 R11_G11_B10 : Vec4<Unorm, Float> = u32 {0}
132 [BufferSurface, TextureSurface, RenderSurface], doc = "",
133 R16 : Vec1<Int, Uint, Inorm, Unorm, Float> = u16 {0}
134 [BufferSurface, TextureSurface, RenderSurface], doc = "",
135 R16_G16 : Vec2<Int, Uint, Inorm, Unorm, Float> = [u16; 2] {0}
136 [BufferSurface, TextureSurface, RenderSurface], doc = "",
137 R16_G16_B16 : Vec3<Int, Uint, Inorm, Unorm, Float> = [u16; 3] {0}
138 [BufferSurface, TextureSurface, RenderSurface], doc = "",
139 R16_G16_B16_A16 : Vec4<Int, Uint, Inorm, Unorm, Float> = [u16; 4] {16}
140 [BufferSurface, TextureSurface, RenderSurface], doc = "",
141 R32 : Vec1<Int, Uint, Float> = u32 {0}
142 [BufferSurface, TextureSurface, RenderSurface], doc = "",
143 R32_G32 : Vec2<Int, Uint, Float> = [u32; 2] {0}
144 [BufferSurface, TextureSurface, RenderSurface], doc = "",
145 R32_G32_B32 : Vec3<Int, Uint, Float> = [u32; 3] {0}
146 [BufferSurface, TextureSurface, RenderSurface], doc = "",
147 R32_G32_B32_A32 : Vec4<Int, Uint, Float> = [u32; 4] {32}
148 [BufferSurface, TextureSurface, RenderSurface], doc = "",
149 B8_G8_R8_A8 : Vec4<Unorm, Srgb> = [u8; 4] {32}
150 [BufferSurface, TextureSurface, RenderSurface], doc = "",
151 D16 : Vec1<Unorm> = F16 {0} [TextureSurface, DepthSurface], doc = "",
152 D24 : Vec1<Unorm> = f32 {8} [TextureSurface, DepthSurface], doc = "", D24_S8 : Vec1<Unorm, Uint> = u32 {8} [TextureSurface, DepthSurface, StencilSurface], doc = "",
154 D32 : Vec1<Float> = f32 {0} [TextureSurface, DepthSurface], doc = "",
155 BC1_R8_G8_B8 : Vec4<Int, Uint, Inorm, Unorm, Srgb> = [u8; 3] {0} [TextureSurface],
158 doc = "Block Compression 1 also known as DXT1, S3TC. See \
159 [S3TC wiki](https://wikipedia.org/wiki/S3_Texture_Compression).\
160 \n\nCurrently supported in the gfx_device_gl backend only.",
161 BC3_R8_G8_B8_A8 : Vec4<Int, Uint, Inorm, Unorm, Srgb> = [u8; 4] {8} [TextureSurface],
162 doc = "Block Compression 3 also known as DXT5, S3TC. See \
163 [S3TC wiki](https://wikipedia.org/wiki/S3_Texture_Compression).\
164 \n\nCurrently supported in the gfx_device_gl backend only.",
165}
166
167
168#[allow(missing_docs)]
171#[repr(u8)]
172#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
173#[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
174pub enum ChannelSource {
175 Zero,
176 One,
177 X,
178 Y,
179 Z,
180 W,
181}
182
183#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
187#[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
188pub struct Swizzle(pub ChannelSource, pub ChannelSource, pub ChannelSource, pub ChannelSource);
189
190impl Swizzle {
191 pub fn new() -> Swizzle {
193 Swizzle(ChannelSource::X, ChannelSource::Y, ChannelSource::Z, ChannelSource::W)
194 }
195}
196
197#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
199#[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
200pub struct Format(pub SurfaceType, pub ChannelType);
201
202pub trait SurfaceTyped {
204 type DataType: Pod;
206 fn get_surface_type() -> SurfaceType;
208}
209pub trait BufferSurface: SurfaceTyped {}
211pub trait TextureSurface: SurfaceTyped {}
213pub trait RenderSurface: SurfaceTyped {}
215pub trait DepthSurface: SurfaceTyped {}
217pub trait StencilSurface: SurfaceTyped {}
219
220pub trait ChannelTyped {
222 type ShaderType;
225 fn get_channel_type() -> ChannelType;
227}
228pub trait TextureChannel: ChannelTyped {}
230pub trait RenderChannel: ChannelTyped {}
232pub trait BlendChannel: RenderChannel {}
234
235pub trait Formatted {
237 type Surface: SurfaceTyped;
239 type Channel: ChannelTyped;
241 type View;
243 fn get_format() -> Format {
245 Format(
246 Self::Surface::get_surface_type(),
247 Self::Channel::get_channel_type())
248 }
249}
250pub trait BufferFormat: Formatted {}
252pub trait DepthFormat: Formatted {}
254pub trait StencilFormat: Formatted {}
256pub trait DepthStencilFormat: DepthFormat + StencilFormat {}
258pub trait TextureFormat: Formatted {}
260pub trait RenderFormat: Formatted {}
262pub trait BlendFormat: RenderFormat {}
264
265impl<F> BufferFormat for F where
266 F: Formatted,
267 F::Surface: BufferSurface,
268 F::Channel: ChannelTyped,
269{}
270impl<F> DepthFormat for F where
271 F: Formatted,
272 F::Surface: DepthSurface,
273 F::Channel: RenderChannel,
274{}
275impl<F> StencilFormat for F where
276 F: Formatted,
277 F::Surface: StencilSurface,
278 F::Channel: RenderChannel,
279{}
280impl<F> DepthStencilFormat for F where
281 F: DepthFormat + StencilFormat
282{}
283impl<F> TextureFormat for F where
284 F: Formatted,
285 F::Surface: TextureSurface,
286 F::Channel: TextureChannel,
287{}
288impl<F> RenderFormat for F where
289 F: Formatted,
290 F::Surface: RenderSurface,
291 F::Channel: RenderChannel,
292{}
293impl<F> BlendFormat for F where
294 F: Formatted,
295 F::Surface: RenderSurface,
296 F::Channel: BlendChannel,
297{}
298
299macro_rules! alias {
300 { $( $name:ident = $ty:ty, )* } => {
301 $(
302 #[allow(missing_docs)]
303 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
304 #[cfg_attr(feature="serialize", derive(Serialize, Deserialize))]
305 pub struct $name(pub $ty);
306 impl From<$ty> for $name {
307 fn from(v: $ty) -> $name {
308 $name(v)
309 }
310 }
311
312 unsafe impl Pod for $name {}
313
314 impl $name {
315 pub fn cast2(v: [$ty; 2]) -> [$name; 2] {
317 [$name(v[0]), $name(v[1])]
318 }
319 pub fn cast3(v: [$ty; 3]) -> [$name; 3] {
321 [$name(v[0]), $name(v[1]), $name(v[2])]
322 }
323 pub fn cast4(v: [$ty; 4]) -> [$name; 4] {
325 [$name(v[0]), $name(v[1]), $name(v[2]), $name(v[3])]
326 }
327 pub fn cast_slice(slice: &[$ty]) -> &[$name] {
329 use std::mem::transmute;
330 unsafe { transmute(slice) }
331 }
332 }
333 )*
334 }
335}
336
337alias! {
338 U8Norm = u8,
339 I8Norm = i8,
340 U16Norm = u16,
341 I16Norm = i16,
342 F16 = u16, }
344
345pub type Vec1<T> = T;
347pub type Vec2<T> = [T; 2];
349pub type Vec3<T> = [T; 3];
351pub type Vec4<T> = [T; 4];
353
354pub type Rgba8 = (R8_G8_B8_A8, Unorm);
356pub type Srgba8 = (R8_G8_B8_A8, Srgb);
358pub type Rgb10a2F = (R10_G10_B10_A2, Float);
361pub type Rgba16F = (R16_G16_B16_A16, Float);
363pub type Rgba32F = (R32_G32_B32_A32, Float);
365pub type Bgra8 = (B8_G8_R8_A8, Unorm);
367pub type Depth = (D24, Unorm);
369pub type DepthStencil = (D24_S8, Unorm);
371pub type Depth32F = (D32, Float);
373
374macro_rules! impl_simple_formats {
375 { $( $container:ident< $ty:ty > = $channel:ident $surface:ident, )* } => {
376 $(
377 impl Formatted for $container<$ty> {
378 type Surface = $surface;
379 type Channel = $channel;
380 type View = $container<<$channel as ChannelTyped>::ShaderType>;
381 }
382 )*
383 }
384}
385
386macro_rules! impl_formats_8bit {
387 { $( $ty:ty = $channel:ident, )* } => {
388 impl_simple_formats! {$(
389 Vec1<$ty> = $channel R8,
390 Vec2<$ty> = $channel R8_G8,
391 Vec4<$ty> = $channel R8_G8_B8_A8,
392 )*}
393 }
394}
395
396macro_rules! impl_formats_16bit {
397 { $( $ty:ty = $channel:ident, )* } => {
398 impl_simple_formats! {$(
399 Vec1<$ty> = $channel R16,
400 Vec2<$ty> = $channel R16_G16,
401 Vec3<$ty> = $channel R16_G16_B16,
402 Vec4<$ty> = $channel R16_G16_B16_A16,
403 )*}
404 }
405}
406
407macro_rules! impl_formats_32bit {
408 { $( $ty:ty = $channel:ident, )* } => {
409 impl_simple_formats! {$(
410 Vec1<$ty> = $channel R32,
411 Vec2<$ty> = $channel R32_G32,
412 Vec3<$ty> = $channel R32_G32_B32,
413 Vec4<$ty> = $channel R32_G32_B32_A32,
414 )*}
415 }
416}
417
418impl_formats_8bit! {
419 u8 = Uint,
420 i8 = Int,
421 U8Norm = Unorm,
422 I8Norm = Inorm,
423}
424
425impl_formats_16bit! {
426 u16 = Uint,
427 i16 = Int,
428 U16Norm = Unorm,
429 I16Norm = Inorm,
430 F16 = Float,
431}
432
433impl_formats_32bit! {
434 u32 = Uint,
435 i32 = Int,
436 f32 = Float,
437}