• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2017 The vulkano developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or
4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
6 // at your option. All files in the project carrying such
7 // notice may not be copied, modified, or distributed except
8 // according to those terms.
9 
10 use crate::pipeline::vertex::VertexMemberTy;
11 
12 /// Implements the `Vertex` trait on a struct.
13 ///# Example
14 ///
15 ///```
16 ///#[derive(Default, Copy, Clone)]
17 ///struct Vertex{
18 ///  position: [f32; 3],
19 ///  color: [f32; 4]
20 ///}
21 ///
22 ///vulkano::impl_vertex!(Vertex, position, color);
23 ///
24 ///```
25 #[macro_export]
26 macro_rules! impl_vertex {
27     ($out:ty $(, $member:ident)*) => (
28         #[allow(unsafe_code)]
29         unsafe impl $crate::pipeline::vertex::Vertex for $out {
30             #[inline(always)]
31             fn member(name: &str) -> Option<$crate::pipeline::vertex::VertexMemberInfo> {
32                 use std::ptr;
33                 #[allow(unused_imports)]
34                 use $crate::format::Format;
35                 use $crate::pipeline::vertex::VertexMemberInfo;
36                 use $crate::pipeline::vertex::VertexMemberTy;
37                 use $crate::pipeline::vertex::VertexMember;
38 
39                 $(
40                     if name == stringify!($member) {
41                         let dummy = <$out>::default();
42                         #[inline] fn f<T: VertexMember>(_: &T) -> (VertexMemberTy, usize) { T::format() }
43                         let (ty, array_size) = f(&dummy.$member);
44 
45                         let dummy_ptr = (&dummy) as *const _;
46                         let member_ptr = (&dummy.$member) as *const _;
47 
48                         return Some(VertexMemberInfo {
49                             offset: member_ptr as usize - dummy_ptr as usize,
50                             ty: ty,
51                             array_size: array_size,
52                         });
53                     }
54                 )*
55 
56                 None
57             }
58         }
59     )
60 }
61 
62 /// Trait for data types that can be used as vertex members. Used by the `impl_vertex!` macro.
63 pub unsafe trait VertexMember {
64     /// Returns the format and array size of the member.
format() -> (VertexMemberTy, usize)65     fn format() -> (VertexMemberTy, usize);
66 }
67 
68 unsafe impl VertexMember for i8 {
69     #[inline]
format() -> (VertexMemberTy, usize)70     fn format() -> (VertexMemberTy, usize) {
71         (VertexMemberTy::I8, 1)
72     }
73 }
74 
75 unsafe impl VertexMember for u8 {
76     #[inline]
format() -> (VertexMemberTy, usize)77     fn format() -> (VertexMemberTy, usize) {
78         (VertexMemberTy::U8, 1)
79     }
80 }
81 
82 unsafe impl VertexMember for i16 {
83     #[inline]
format() -> (VertexMemberTy, usize)84     fn format() -> (VertexMemberTy, usize) {
85         (VertexMemberTy::I16, 1)
86     }
87 }
88 
89 unsafe impl VertexMember for u16 {
90     #[inline]
format() -> (VertexMemberTy, usize)91     fn format() -> (VertexMemberTy, usize) {
92         (VertexMemberTy::U16, 1)
93     }
94 }
95 
96 unsafe impl VertexMember for i32 {
97     #[inline]
format() -> (VertexMemberTy, usize)98     fn format() -> (VertexMemberTy, usize) {
99         (VertexMemberTy::I32, 1)
100     }
101 }
102 
103 unsafe impl VertexMember for u32 {
104     #[inline]
format() -> (VertexMemberTy, usize)105     fn format() -> (VertexMemberTy, usize) {
106         (VertexMemberTy::U32, 1)
107     }
108 }
109 
110 unsafe impl VertexMember for f32 {
111     #[inline]
format() -> (VertexMemberTy, usize)112     fn format() -> (VertexMemberTy, usize) {
113         (VertexMemberTy::F32, 1)
114     }
115 }
116 
117 unsafe impl VertexMember for f64 {
118     #[inline]
format() -> (VertexMemberTy, usize)119     fn format() -> (VertexMemberTy, usize) {
120         (VertexMemberTy::F64, 1)
121     }
122 }
123 
124 unsafe impl<T> VertexMember for (T,)
125 where
126     T: VertexMember,
127 {
128     #[inline]
format() -> (VertexMemberTy, usize)129     fn format() -> (VertexMemberTy, usize) {
130         <T as VertexMember>::format()
131     }
132 }
133 
134 unsafe impl<T> VertexMember for (T, T)
135 where
136     T: VertexMember,
137 {
138     #[inline]
format() -> (VertexMemberTy, usize)139     fn format() -> (VertexMemberTy, usize) {
140         let (ty, sz) = <T as VertexMember>::format();
141         (ty, sz * 2)
142     }
143 }
144 
145 unsafe impl<T> VertexMember for (T, T, T)
146 where
147     T: VertexMember,
148 {
149     #[inline]
format() -> (VertexMemberTy, usize)150     fn format() -> (VertexMemberTy, usize) {
151         let (ty, sz) = <T as VertexMember>::format();
152         (ty, sz * 3)
153     }
154 }
155 
156 unsafe impl<T> VertexMember for (T, T, T, T)
157 where
158     T: VertexMember,
159 {
160     #[inline]
format() -> (VertexMemberTy, usize)161     fn format() -> (VertexMemberTy, usize) {
162         let (ty, sz) = <T as VertexMember>::format();
163         (ty, sz * 4)
164     }
165 }
166 
167 macro_rules! impl_vm_array {
168     ($sz:expr) => {
169         unsafe impl<T> VertexMember for [T; $sz]
170         where
171             T: VertexMember,
172         {
173             #[inline]
174             fn format() -> (VertexMemberTy, usize) {
175                 let (ty, sz) = <T as VertexMember>::format();
176                 (ty, sz * $sz)
177             }
178         }
179     };
180 }
181 
182 impl_vm_array!(1);
183 impl_vm_array!(2);
184 impl_vm_array!(3);
185 impl_vm_array!(4);
186 impl_vm_array!(5);
187 impl_vm_array!(6);
188 impl_vm_array!(7);
189 impl_vm_array!(8);
190 impl_vm_array!(9);
191 impl_vm_array!(10);
192 impl_vm_array!(11);
193 impl_vm_array!(12);
194 impl_vm_array!(13);
195 impl_vm_array!(14);
196 impl_vm_array!(15);
197 impl_vm_array!(16);
198 impl_vm_array!(32);
199 impl_vm_array!(64);
200