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