glium/vertex/
format.rs

1use std::borrow::Cow;
2use std::mem;
3
4use crate::version::Api;
5use crate::version::Version;
6use crate::vertex::Attribute;
7use crate::CapabilitiesSource;
8
9#[allow(missing_docs)]
10#[derive(Copy, Clone, Debug, PartialEq, Eq)]
11pub enum AttributeType {
12    I8,
13    I8I8,
14    I8I8I8,
15    I8I8I8I8,
16    U8,
17    U8U8,
18    U8U8U8,
19    U8U8U8U8,
20    I16,
21    I16I16,
22    I16I16I16,
23    I16I16I16I16,
24    U16,
25    U16U16,
26    U16U16U16,
27    U16U16U16U16,
28    I32,
29    I32I32,
30    I32I32I32,
31    I32I32I32I32,
32    U32,
33    U32U32,
34    U32U32U32,
35    U32U32U32U32,
36    I64,
37    I64I64,
38    I64I64I64,
39    I64I64I64I64,
40    U64,
41    U64U64,
42    U64U64U64,
43    U64U64U64U64,
44    F16,
45    F16F16,
46    F16F16F16,
47    F16F16F16F16,
48    /// 2x2 matrix of `f16`s
49    F16x2x2,
50    /// 2x3 matrix of `f16`s
51    F16x2x3,
52    /// 2x3 matrix of `f16`s
53    F16x2x4,
54    /// 3x2 matrix of `f16`s
55    F16x3x2,
56    /// 3x3 matrix of `f16`s
57    F16x3x3,
58    /// 3x4 matrix of `f16`s
59    F16x3x4,
60    /// 4x2 matrix of `f16`s
61    F16x4x2,
62    /// 4x3 matrix of `f16`s
63    F16x4x3,
64    /// 4x4 matrix of `f16`s
65    F16x4x4,
66    F32,
67    F32F32,
68    F32F32F32,
69    F32F32F32F32,
70    /// 2x2 matrix of `f32`s
71    F32x2x2,
72    /// 2x3 matrix of `f32`s
73    F32x2x3,
74    /// 2x3 matrix of `f32`s
75    F32x2x4,
76    /// 3x2 matrix of `f32`s
77    F32x3x2,
78    /// 3x3 matrix of `f32`s
79    F32x3x3,
80    /// 3x4 matrix of `f32`s
81    F32x3x4,
82    /// 4x2 matrix of `f32`s
83    F32x4x2,
84    /// 4x3 matrix of `f32`s
85    F32x4x3,
86    /// 4x4 matrix of `f32`s
87    F32x4x4,
88    /// Warning: using `f64`s can be very slow.
89    F64,
90    /// Warning: using `f64`s can be very slow.
91    F64F64,
92    /// Warning: using `f64`s can be very slow.
93    F64F64F64,
94    /// Warning: using `f64`s can be very slow.
95    F64F64F64F64,
96    /// 2x2 matrix of `f64`s
97    /// Warning: using `f64`s can be very slow.
98    F64x2x2,
99    /// 2x3 matrix of `f64`s
100    /// Warning: using `f64`s can be very slow.
101    F64x2x3,
102    /// 2x3 matrix of `f64`s
103    /// Warning: using `f64`s can be very slow.
104    F64x2x4,
105    /// 3x2 matrix of `f64`s
106    /// Warning: using `f64`s can be very slow.
107    F64x3x2,
108    /// 3x3 matrix of `f64`s
109    /// Warning: using `f64`s can be very slow.
110    F64x3x3,
111    /// 3x4 matrix of `f64`s
112    /// Warning: using `f64`s can be very slow.
113    F64x3x4,
114    /// 4x2 matrix of `f64`s
115    /// Warning: using `f64`s can be very slow.
116    F64x4x2,
117    /// 4x3 matrix of `f64`s
118    /// Warning: using `f64`s can be very slow.
119    F64x4x3,
120    /// 4x4 matrix of `f64`s
121    /// Warning: using `f64`s can be very slow.
122    F64x4x4,
123    /// From MSB to LSB: two bits for the alpha, ten bits for the blue, ten bits for the green,
124    /// ten bits for the red.
125    ///
126    /// Corresponds to `GL_INT_2_10_10_10_REV`.
127    I2I10I10I10Reversed,
128    /// From MSB to LSB: two bits for the alpha, ten bits for the blue, ten bits for the green,
129    /// ten bits for the red.
130    ///
131    /// Corresponds to `GL_UNSIGNED_INT_2_10_10_10_REV`.
132    U2U10U10U10Reversed,
133    /// Corresponds to `GL_INT_10_10_10_2`.
134    I10I10I10I2,
135    /// Corresponds to `GL_UNSIGNED_INT_10_10_10_2`.
136    U10U10U10U2,
137    /// Three floating points values turned into unsigned integers./
138    ///
139    /// Corresponds to `GL_UNSIGNED_INT_10F_11F_11F_REV`.
140    F10F11F11UnsignedIntReversed,
141    /// Fixed floating points. A 16bits signed value followed by the 16bits unsigned exponent.
142    ///
143    /// Corresponds to `GL_FIXED`.
144    FixedFloatI16U16,
145}
146
147impl AttributeType {
148    /// Returns true if the backend supports this type of attribute.
149    pub fn is_supported<C: ?Sized>(&self, caps: &C) -> bool where C: CapabilitiesSource {
150        match self {
151            &AttributeType::I8 | &AttributeType::I8I8 | &AttributeType::I8I8I8 |
152            &AttributeType::I8I8I8I8 | &AttributeType::U8 | &AttributeType::U8U8 |
153            &AttributeType::U8U8U8 | &AttributeType::U8U8U8U8 | &AttributeType::I16 |
154            &AttributeType::I16I16 | &AttributeType::I16I16I16 | &AttributeType::I16I16I16I16 |
155            &AttributeType::U16 | &AttributeType::U16U16 | &AttributeType::U16U16U16 |
156            &AttributeType::U16U16U16U16 | &AttributeType::F32 |
157            &AttributeType::F32F32 | &AttributeType::F32F32F32 | &AttributeType::F32F32F32F32 |
158            &AttributeType::F32x2x2 | &AttributeType::F32x2x3 | &AttributeType::F32x2x4 |
159            &AttributeType::F32x3x2 | &AttributeType::F32x3x3 | &AttributeType::F32x3x4 |
160            &AttributeType::F32x4x2 | &AttributeType::F32x4x3 | &AttributeType::F32x4x4 =>
161            {
162                true
163            },
164
165            &AttributeType::I32 | &AttributeType::I32I32 | &AttributeType::I32I32I32 |
166            &AttributeType::I32I32I32I32 | &AttributeType::U32 | &AttributeType::U32U32 |
167            &AttributeType::U32U32U32 | &AttributeType::U32U32U32U32 =>
168            {
169                caps.get_version() >= &Version(Api::Gl, 1, 0) ||
170                caps.get_version() >= &Version(Api::GlEs, 3, 0)
171            },
172
173            &AttributeType::I64 | &AttributeType::I64I64 | &AttributeType::I64I64I64 |
174            &AttributeType::I64I64I64I64 =>
175            {
176                caps.get_extensions().gl_nv_vertex_attrib_integer_64bit
177            },
178
179            &AttributeType::U64 | &AttributeType::U64U64 |
180            &AttributeType::U64U64U64 | &AttributeType::U64U64U64U64 =>
181            {
182                caps.get_extensions().gl_arb_bindless_texture ||
183                caps.get_extensions().gl_nv_vertex_attrib_integer_64bit
184            },
185
186            &AttributeType::F64 | &AttributeType::F64F64 | &AttributeType::F64F64F64 |
187            &AttributeType::F64F64F64F64 | &AttributeType::F64x2x2 | &AttributeType::F64x2x3 |
188            &AttributeType::F64x2x4 | &AttributeType::F64x3x2 | &AttributeType::F64x3x3 |
189            &AttributeType::F64x3x4 | &AttributeType::F64x4x2 | &AttributeType::F64x4x3 |
190            &AttributeType::F64x4x4 =>
191            {
192                caps.get_version() >= &Version(Api::Gl, 1, 0)
193            },
194
195            &AttributeType::F16 | &AttributeType::F16F16 | &AttributeType::F16F16F16 |
196            &AttributeType::F16F16F16F16 |
197            &AttributeType::F16x2x2 | &AttributeType::F16x2x3 | &AttributeType::F16x2x4 |
198            &AttributeType::F16x3x2 | &AttributeType::F16x3x3 | &AttributeType::F16x3x4 |
199            &AttributeType::F16x4x2 | &AttributeType::F16x4x3 | &AttributeType::F16x4x4 =>
200            {
201                caps.get_version() >= &Version(Api::GlEs, 3, 0) ||
202                caps.get_version() >= &Version(Api::Gl, 4, 0) ||
203                caps.get_extensions().gl_arb_es3_compatibility ||
204                caps.get_extensions().gl_oes_vertex_half_float ||
205                caps.get_extensions().gl_arb_vertex_half_float ||
206                caps.get_extensions().gl_nv_half_float
207            },
208
209            &AttributeType::FixedFloatI16U16 => {
210                caps.get_version() >= &Version(Api::GlEs, 2, 0) ||
211                caps.get_version() >= &Version(Api::Gl, 4, 0) ||
212                caps.get_extensions().gl_arb_es2_compatibility ||
213                caps.get_extensions().gl_oes_fixed_point
214            },
215
216            &AttributeType::I2I10I10I10Reversed | &AttributeType::U2U10U10U10Reversed => {
217                caps.get_version() >= &Version(Api::Gl, 3, 0) ||
218                caps.get_version() >= &Version(Api::GlEs, 3, 0) ||
219                caps.get_extensions().gl_arb_vertex_type_2_10_10_10_rev ||
220                caps.get_extensions().gl_arb_es3_compatibility
221            },
222
223            &AttributeType::I10I10I10I2 | &AttributeType::U10U10U10U2 => {
224                caps.get_extensions().gl_oes_vertex_type_10_10_10_2
225            },
226
227            &AttributeType::F10F11F11UnsignedIntReversed => {
228                caps.get_version() >= &Version(Api::Gl, 4, 0) ||
229                caps.get_extensions().gl_arb_vertex_type_10f_11f_11f_rev
230            },
231        }
232    }
233
234    /// Returns the size in bytes of a value of this type.
235    pub fn get_size_bytes(&self) -> usize {
236        match *self {
237            AttributeType::I8 => 1 * mem::size_of::<i8>(),
238            AttributeType::I8I8 => 2 * mem::size_of::<i8>(),
239            AttributeType::I8I8I8 => 3 * mem::size_of::<i8>(),
240            AttributeType::I8I8I8I8 => 4 * mem::size_of::<i8>(),
241            AttributeType::U8 => 1 * mem::size_of::<u8>(),
242            AttributeType::U8U8 => 2 * mem::size_of::<u8>(),
243            AttributeType::U8U8U8 => 3 * mem::size_of::<u8>(),
244            AttributeType::U8U8U8U8 => 4 * mem::size_of::<u8>(),
245            AttributeType::I16 => 1 * mem::size_of::<i16>(),
246            AttributeType::I16I16 => 2 * mem::size_of::<i16>(),
247            AttributeType::I16I16I16 => 3 * mem::size_of::<i16>(),
248            AttributeType::I16I16I16I16 => 4 * mem::size_of::<i16>(),
249            AttributeType::U16 => 1 * mem::size_of::<u16>(),
250            AttributeType::U16U16 => 2 * mem::size_of::<u16>(),
251            AttributeType::U16U16U16 => 3 * mem::size_of::<u16>(),
252            AttributeType::U16U16U16U16 => 4 * mem::size_of::<u16>(),
253            AttributeType::I32 => 1 * mem::size_of::<i32>(),
254            AttributeType::I32I32 => 2 * mem::size_of::<i32>(),
255            AttributeType::I32I32I32 => 3 * mem::size_of::<i32>(),
256            AttributeType::I32I32I32I32 => 4 * mem::size_of::<i32>(),
257            AttributeType::U32 => 1 * mem::size_of::<u32>(),
258            AttributeType::U32U32 => 2 * mem::size_of::<u32>(),
259            AttributeType::U32U32U32 => 3 * mem::size_of::<u32>(),
260            AttributeType::U32U32U32U32 => 4 * mem::size_of::<u32>(),
261            AttributeType::I64 => 1 * mem::size_of::<i64>(),
262            AttributeType::I64I64 => 2 * mem::size_of::<i64>(),
263            AttributeType::I64I64I64 => 3 * mem::size_of::<i64>(),
264            AttributeType::I64I64I64I64 => 4 * mem::size_of::<i64>(),
265            AttributeType::U64 => 1 * mem::size_of::<u64>(),
266            AttributeType::U64U64 => 2 * mem::size_of::<u64>(),
267            AttributeType::U64U64U64 => 3 * mem::size_of::<u64>(),
268            AttributeType::U64U64U64U64 => 4 * mem::size_of::<u64>(),
269            AttributeType::F16 => 1 * 2,
270            AttributeType::F16F16 => 2 * 2,
271            AttributeType::F16F16F16 => 3 * 2,
272            AttributeType::F16F16F16F16 => 4 * 2,
273            AttributeType::F16x2x2 => 4 * 2,
274            AttributeType::F16x2x3 => 6 * 2,
275            AttributeType::F16x2x4 => 8 * 2,
276            AttributeType::F16x3x2 => 6 * 2,
277            AttributeType::F16x3x3 => 9 * 2,
278            AttributeType::F16x3x4 => 12 * 2,
279            AttributeType::F16x4x2 => 8 * 2,
280            AttributeType::F16x4x3 => 12 * 2,
281            AttributeType::F16x4x4 => 16 * 2,
282            AttributeType::F32 => 1 * mem::size_of::<f32>(),
283            AttributeType::F32F32 => 2 * mem::size_of::<f32>(),
284            AttributeType::F32F32F32 => 3 * mem::size_of::<f32>(),
285            AttributeType::F32F32F32F32 => 4 * mem::size_of::<f32>(),
286            AttributeType::F32x2x2 => 4 * mem::size_of::<f32>(),
287            AttributeType::F32x2x3 => 6 * mem::size_of::<f32>(),
288            AttributeType::F32x2x4 => 8 * mem::size_of::<f32>(),
289            AttributeType::F32x3x2 => 6 * mem::size_of::<f32>(),
290            AttributeType::F32x3x3 => 9 * mem::size_of::<f32>(),
291            AttributeType::F32x3x4 => 12 * mem::size_of::<f32>(),
292            AttributeType::F32x4x2 => 8 * mem::size_of::<f32>(),
293            AttributeType::F32x4x3 => 12 * mem::size_of::<f32>(),
294            AttributeType::F32x4x4 => 16 * mem::size_of::<f32>(),
295            AttributeType::F64 => 1 * mem::size_of::<f64>(),
296            AttributeType::F64F64 => 2 * mem::size_of::<f64>(),
297            AttributeType::F64F64F64 => 3 * mem::size_of::<f64>(),
298            AttributeType::F64F64F64F64 => 4 * mem::size_of::<f64>(),
299            AttributeType::F64x2x2 => 4 * mem::size_of::<f64>(),
300            AttributeType::F64x2x3 => 6 * mem::size_of::<f64>(),
301            AttributeType::F64x2x4 => 8 * mem::size_of::<f64>(),
302            AttributeType::F64x3x2 => 6 * mem::size_of::<f64>(),
303            AttributeType::F64x3x3 => 9 * mem::size_of::<f64>(),
304            AttributeType::F64x3x4 => 12 * mem::size_of::<f64>(),
305            AttributeType::F64x4x2 => 8 * mem::size_of::<f64>(),
306            AttributeType::F64x4x3 => 12 * mem::size_of::<f64>(),
307            AttributeType::F64x4x4 => 16 * mem::size_of::<f64>(),
308            AttributeType::I2I10I10I10Reversed => 4,
309            AttributeType::U2U10U10U10Reversed => 4,
310            AttributeType::I10I10I10I2 => 4,
311            AttributeType::U10U10U10U2 => 4,
312            AttributeType::F10F11F11UnsignedIntReversed => 4,
313            AttributeType::FixedFloatI16U16 => 4,
314        }
315    }
316
317    /// Returns the number of values for this type.
318    pub fn get_num_components(&self) -> usize {
319        match *self {
320            AttributeType::I8 => 1,
321            AttributeType::I8I8 => 2,
322            AttributeType::I8I8I8 => 3,
323            AttributeType::I8I8I8I8 => 4,
324            AttributeType::U8 => 1,
325            AttributeType::U8U8 => 2,
326            AttributeType::U8U8U8 => 3,
327            AttributeType::U8U8U8U8 => 4,
328            AttributeType::I16 => 1,
329            AttributeType::I16I16 => 2,
330            AttributeType::I16I16I16 => 3,
331            AttributeType::I16I16I16I16 => 4,
332            AttributeType::U16 => 1,
333            AttributeType::U16U16 => 2,
334            AttributeType::U16U16U16 => 3,
335            AttributeType::U16U16U16U16 => 4,
336            AttributeType::I32 => 1,
337            AttributeType::I32I32 => 2,
338            AttributeType::I32I32I32 => 3,
339            AttributeType::I32I32I32I32 => 4,
340            AttributeType::U32 => 1,
341            AttributeType::U32U32 => 2,
342            AttributeType::U32U32U32 => 3,
343            AttributeType::U32U32U32U32 => 4,
344            AttributeType::I64 => 1,
345            AttributeType::I64I64 => 2,
346            AttributeType::I64I64I64 => 3,
347            AttributeType::I64I64I64I64 => 4,
348            AttributeType::U64 => 1,
349            AttributeType::U64U64 => 2,
350            AttributeType::U64U64U64 => 3,
351            AttributeType::U64U64U64U64 => 4,
352            AttributeType::F16 => 1,
353            AttributeType::F16F16 => 2,
354            AttributeType::F16F16F16 => 3,
355            AttributeType::F16F16F16F16 => 4,
356            AttributeType::F16x2x2 => 4,
357            AttributeType::F16x2x3 => 6,
358            AttributeType::F16x2x4 => 8,
359            AttributeType::F16x3x2 => 6,
360            AttributeType::F16x3x3 => 9,
361            AttributeType::F16x3x4 => 12,
362            AttributeType::F16x4x2 => 8,
363            AttributeType::F16x4x3 => 12,
364            AttributeType::F16x4x4 => 16,
365            AttributeType::F32 => 1,
366            AttributeType::F32F32 => 2,
367            AttributeType::F32F32F32 => 3,
368            AttributeType::F32F32F32F32 => 4,
369            AttributeType::F32x2x2 => 4,
370            AttributeType::F32x2x3 => 6,
371            AttributeType::F32x2x4 => 8,
372            AttributeType::F32x3x2 => 6,
373            AttributeType::F32x3x3 => 9,
374            AttributeType::F32x3x4 => 12,
375            AttributeType::F32x4x2 => 8,
376            AttributeType::F32x4x3 => 12,
377            AttributeType::F32x4x4 => 16,
378            AttributeType::F64 => 1,
379            AttributeType::F64F64 => 2,
380            AttributeType::F64F64F64 => 3,
381            AttributeType::F64F64F64F64 => 4,
382            AttributeType::F64x2x2 => 4,
383            AttributeType::F64x2x3 => 6,
384            AttributeType::F64x2x4 => 8,
385            AttributeType::F64x3x2 => 6,
386            AttributeType::F64x3x3 => 9,
387            AttributeType::F64x3x4 => 12,
388            AttributeType::F64x4x2 => 8,
389            AttributeType::F64x4x3 => 12,
390            AttributeType::F64x4x4 => 16,
391            AttributeType::I2I10I10I10Reversed => 4,
392            AttributeType::U2U10U10U10Reversed => 4,
393            AttributeType::I10I10I10I2 => 4,
394            AttributeType::U10U10U10U2 => 4,
395            AttributeType::F10F11F11UnsignedIntReversed => 3,
396            AttributeType::FixedFloatI16U16 => 1,
397        }
398    }
399}
400
401/// Describes the layout of each vertex in a vertex buffer.
402///
403/// The first element is the name of the binding, the second element
404/// is the offset from the start of each vertex to this element, the
405/// third element is the layout location specified in the shader, the
406/// fourth element is the type and the fifth element indicates whether
407/// or not the element should use fixed-point normalization when
408/// binding in a VAO.
409pub type VertexFormat = &'static [(Cow<'static, str>, usize, i32, AttributeType, bool)];
410
411unsafe impl Attribute for i8 {
412    const TYPE: AttributeType = AttributeType::I8;
413}
414
415unsafe impl Attribute for (i8, i8) {
416    const TYPE: AttributeType = AttributeType::I8I8;
417}
418
419unsafe impl Attribute for [i8; 2] {
420    const TYPE: AttributeType = AttributeType::I8I8;
421}
422
423unsafe impl Attribute for (i8, i8, i8) {
424    const TYPE: AttributeType = AttributeType::I8I8I8;
425}
426
427unsafe impl Attribute for [i8; 3] {
428    const TYPE: AttributeType = AttributeType::I8I8I8;
429}
430
431unsafe impl Attribute for (i8, i8, i8, i8) {
432    const TYPE: AttributeType = AttributeType::I8I8I8I8;
433}
434
435unsafe impl Attribute for [i8; 4] {
436    const TYPE: AttributeType = AttributeType::I8I8I8I8;
437}
438
439unsafe impl Attribute for u8 {
440    const TYPE: AttributeType = AttributeType::U8;
441}
442
443unsafe impl Attribute for (u8, u8) {
444    const TYPE: AttributeType = AttributeType::U8U8;
445}
446
447unsafe impl Attribute for [u8; 2] {
448    const TYPE: AttributeType = AttributeType::U8U8;
449}
450
451unsafe impl Attribute for (u8, u8, u8) {
452    const TYPE: AttributeType = AttributeType::U8U8U8;
453}
454
455unsafe impl Attribute for [u8; 3] {
456    const TYPE: AttributeType = AttributeType::U8U8U8;
457}
458
459unsafe impl Attribute for (u8, u8, u8, u8) {
460    const TYPE: AttributeType = AttributeType::U8U8U8U8;
461}
462
463unsafe impl Attribute for [u8; 4] {
464    const TYPE: AttributeType = AttributeType::U8U8U8U8;
465}
466
467unsafe impl Attribute for i16 {
468    const TYPE: AttributeType = AttributeType::I16;
469}
470
471unsafe impl Attribute for (i16, i16) {
472    const TYPE: AttributeType = AttributeType::I16I16;
473}
474
475unsafe impl Attribute for [i16; 2] {
476    const TYPE: AttributeType = AttributeType::I16I16;
477}
478
479unsafe impl Attribute for (i16, i16, i16) {
480    const TYPE: AttributeType = AttributeType::I16I16I16;
481}
482
483unsafe impl Attribute for [i16; 3] {
484    const TYPE: AttributeType = AttributeType::I16I16I16;
485}
486
487unsafe impl Attribute for (i16, i16, i16, i16) {
488    const TYPE: AttributeType = AttributeType::I16I16I16I16;
489}
490
491unsafe impl Attribute for [i16; 4] {
492    const TYPE: AttributeType = AttributeType::I16I16I16I16;
493}
494
495unsafe impl Attribute for u16 {
496    const TYPE: AttributeType = AttributeType::U16;
497}
498
499unsafe impl Attribute for (u16, u16) {
500    const TYPE: AttributeType = AttributeType::U16U16;
501}
502
503unsafe impl Attribute for [u16; 2] {
504    const TYPE: AttributeType = AttributeType::U16U16;
505}
506
507unsafe impl Attribute for (u16, u16, u16) {
508    const TYPE: AttributeType = AttributeType::U16U16U16;
509}
510
511unsafe impl Attribute for [u16; 3] {
512    const TYPE: AttributeType = AttributeType::U16U16U16;
513}
514
515unsafe impl Attribute for (u16, u16, u16, u16) {
516    const TYPE: AttributeType = AttributeType::U16U16U16U16;
517}
518
519unsafe impl Attribute for [u16; 4] {
520    const TYPE: AttributeType = AttributeType::U16U16U16U16;
521}
522
523unsafe impl Attribute for i32 {
524    const TYPE: AttributeType = AttributeType::I32;
525}
526
527unsafe impl Attribute for (i32, i32) {
528    const TYPE: AttributeType = AttributeType::I32I32;
529}
530
531unsafe impl Attribute for [i32; 2] {
532    const TYPE: AttributeType = AttributeType::I32I32;
533}
534
535unsafe impl Attribute for (i32, i32, i32) {
536    const TYPE: AttributeType = AttributeType::I32I32I32;
537}
538
539unsafe impl Attribute for [i32; 3] {
540    const TYPE: AttributeType = AttributeType::I32I32I32;
541}
542
543unsafe impl Attribute for (i32, i32, i32, i32) {
544    const TYPE: AttributeType = AttributeType::I32I32I32I32;
545}
546
547unsafe impl Attribute for [i32; 4] {
548    const TYPE: AttributeType = AttributeType::I32I32I32I32;
549}
550
551unsafe impl Attribute for u32 {
552    const TYPE: AttributeType = AttributeType::U32;
553}
554
555unsafe impl Attribute for (u32, u32) {
556    const TYPE: AttributeType = AttributeType::U32U32;
557}
558
559unsafe impl Attribute for [u32; 2] {
560    const TYPE: AttributeType = AttributeType::U32U32;
561}
562
563unsafe impl Attribute for (u32, u32, u32) {
564    const TYPE: AttributeType = AttributeType::U32U32U32;
565}
566
567unsafe impl Attribute for [u32; 3] {
568    const TYPE: AttributeType = AttributeType::U32U32U32;
569}
570
571unsafe impl Attribute for (u32, u32, u32, u32) {
572    const TYPE: AttributeType = AttributeType::U32U32U32U32;
573}
574
575unsafe impl Attribute for [u32; 4] {
576    const TYPE: AttributeType = AttributeType::U32U32U32U32;
577}
578
579unsafe impl Attribute for i64 {
580    const TYPE: AttributeType = AttributeType::I64;
581}
582
583unsafe impl Attribute for (i64, i64) {
584    const TYPE: AttributeType = AttributeType::I64I64;
585}
586
587unsafe impl Attribute for [i64; 2] {
588    const TYPE: AttributeType = AttributeType::I64I64;
589}
590
591unsafe impl Attribute for (i64, i64, i64) {
592    const TYPE: AttributeType = AttributeType::I64I64I64;
593}
594
595unsafe impl Attribute for [i64; 3] {
596    const TYPE: AttributeType = AttributeType::I64I64I64;
597}
598
599unsafe impl Attribute for (i64, i64, i64, i64) {
600    const TYPE: AttributeType = AttributeType::I64I64I64I64;
601}
602
603unsafe impl Attribute for [i64; 4] {
604    const TYPE: AttributeType = AttributeType::I64I64I64I64;
605}
606
607unsafe impl Attribute for u64 {
608    const TYPE: AttributeType = AttributeType::U64;
609}
610
611unsafe impl Attribute for (u64, u64) {
612    const TYPE: AttributeType = AttributeType::U64U64;
613}
614
615unsafe impl Attribute for [u64; 2] {
616    const TYPE: AttributeType = AttributeType::U64U64;
617}
618
619unsafe impl Attribute for (u64, u64, u64) {
620    const TYPE: AttributeType = AttributeType::U64U64U64;
621}
622
623unsafe impl Attribute for [u64; 3] {
624    const TYPE: AttributeType = AttributeType::U64U64U64;
625}
626
627unsafe impl Attribute for (u64, u64, u64, u64) {
628    const TYPE: AttributeType = AttributeType::U64U64U64U64;
629}
630
631unsafe impl Attribute for [u64; 4] {
632    const TYPE: AttributeType = AttributeType::U64U64U64U64;
633}
634
635unsafe impl Attribute for f32 {
636    const TYPE: AttributeType = AttributeType::F32;
637}
638
639unsafe impl Attribute for (f32, f32) {
640    const TYPE: AttributeType = AttributeType::F32F32;
641}
642
643unsafe impl Attribute for [f32; 2] {
644    const TYPE: AttributeType = AttributeType::F32F32;
645}
646
647unsafe impl Attribute for (f32, f32, f32) {
648    const TYPE: AttributeType = AttributeType::F32F32F32;
649}
650
651unsafe impl Attribute for [f32; 3] {
652    const TYPE: AttributeType = AttributeType::F32F32F32;
653}
654
655unsafe impl Attribute for (f32, f32, f32, f32) {
656    const TYPE: AttributeType = AttributeType::F32F32F32F32;
657}
658
659unsafe impl Attribute for [f32; 4] {
660    const TYPE: AttributeType = AttributeType::F32F32F32F32;
661}
662
663unsafe impl Attribute for [[f32; 2]; 2] {
664    const TYPE: AttributeType = AttributeType::F32x2x2;
665}
666
667unsafe impl Attribute for [[f32; 3]; 3] {
668    const TYPE: AttributeType = AttributeType::F32x3x3;
669}
670
671unsafe impl Attribute for [[f32; 4]; 4] {
672    const TYPE: AttributeType = AttributeType::F32x4x4;
673}
674
675unsafe impl Attribute for f64 {
676    const TYPE: AttributeType = AttributeType::F64;
677}
678
679unsafe impl Attribute for (f64, f64) {
680    const TYPE: AttributeType = AttributeType::F64F64;
681}
682
683unsafe impl Attribute for [f64; 2] {
684    const TYPE: AttributeType = AttributeType::F64F64;
685}
686
687unsafe impl Attribute for (f64, f64, f64) {
688    const TYPE: AttributeType = AttributeType::F64F64F64;
689}
690
691unsafe impl Attribute for [f64; 3] {
692    const TYPE: AttributeType = AttributeType::F64F64F64;
693}
694
695unsafe impl Attribute for (f64, f64, f64, f64) {
696    const TYPE: AttributeType = AttributeType::F64F64F64F64;
697}
698
699unsafe impl Attribute for [f64; 4] {
700    const TYPE: AttributeType = AttributeType::F64F64F64F64;
701}
702
703unsafe impl Attribute for [[f64; 2]; 2] {
704    const TYPE: AttributeType = AttributeType::F64x2x2;
705}
706
707unsafe impl Attribute for [[f64; 3]; 3] {
708    const TYPE: AttributeType = AttributeType::F64x3x3;
709}
710
711unsafe impl Attribute for [[f64; 4]; 4] {
712    const TYPE: AttributeType = AttributeType::F64x4x4;
713}