1use std::iter::FusedIterator;
4
5#[repr(C)]
6#[allow(non_snake_case)]
7pub struct GenericVulkanStructure {
8 pub sType: crate::vk::VkStructureType,
9 pub pNext: *const core::ffi::c_void,
10 pub _rest: [u8; 0],
11}
12impl GenericVulkanStructure {
13 pub const unsafe fn cast_unchecked<T>(&self) -> &T {
14 unsafe { core::mem::transmute(self) }
15 }
16}
17
18pub unsafe trait VulkanStructure {
19 fn as_generic(&self) -> &GenericVulkanStructure;
21
22 fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure;
24}
25pub unsafe trait TypedVulkanStructure: VulkanStructure + Sized {
26 const TYPE: crate::vk::VkStructureType;
28
29 fn try_from_generic(g: &GenericVulkanStructure) -> Option<&Self> {
31 if g.sType == Self::TYPE {
32 Some(unsafe { g.cast_unchecked() })
33 } else {
34 None
35 }
36 }
37}
38unsafe impl<S: VulkanStructure + ?Sized> VulkanStructure for &'_ mut S {
39 fn as_generic(&self) -> &GenericVulkanStructure {
40 S::as_generic(*self)
41 }
42
43 fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
44 S::as_generic_mut(*self)
45 }
46}
47unsafe impl<S: TypedVulkanStructure + ?Sized> TypedVulkanStructure for &'_ mut S {
48 const TYPE: crate::vk::VkStructureType = S::TYPE;
49}
50unsafe impl<S: VulkanStructure + ?Sized> VulkanStructure for Box<S> {
51 fn as_generic(&self) -> &GenericVulkanStructure {
52 S::as_generic(&**self)
53 }
54
55 fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
56 S::as_generic_mut(&mut **self)
57 }
58}
59unsafe impl<S: TypedVulkanStructure + ?Sized> TypedVulkanStructure for Box<S> {
60 const TYPE: crate::vk::VkStructureType = S::TYPE;
61}
62
63#[repr(C)]
64#[allow(non_snake_case)]
65pub struct GenericVulkanSinkStructure {
66 pub sType: crate::vk::VkStructureType,
67 pub pNext: *mut core::ffi::c_void,
68 _rest: [u8; 0],
69}
70impl GenericVulkanSinkStructure {
71 pub const unsafe fn cast_ref_unchecked<T>(&self) -> &T {
72 unsafe { core::mem::transmute(self) }
73 }
74
75 pub const unsafe fn cast_mut_unchecked<T>(&mut self) -> &mut T {
76 unsafe { core::mem::transmute(self) }
77 }
78}
79
80pub unsafe trait VulkanSinkStructure {
81 fn as_generic(&self) -> &GenericVulkanSinkStructure;
83
84 fn as_generic_mut(&mut self) -> &mut GenericVulkanSinkStructure;
86}
87pub unsafe trait TypedVulkanSinkStructure: VulkanSinkStructure + Sized {
88 const TYPE: crate::vk::VkStructureType;
90
91 fn uninit_sink() -> core::mem::MaybeUninit<Self> {
93 let mut p = core::mem::MaybeUninit::<Self>::uninit();
94 unsafe {
95 let ptr = p.as_mut_ptr() as *mut GenericVulkanSinkStructure;
96 core::ptr::addr_of_mut!((*ptr).sType).write(Self::TYPE);
97 core::ptr::addr_of_mut!((*ptr).pNext).write(core::ptr::null_mut());
98 }
99
100 p
101 }
102
103 fn try_from_generic(g: &GenericVulkanSinkStructure) -> Option<&Self> {
105 if g.sType == Self::TYPE {
106 Some(unsafe { g.cast_ref_unchecked() })
107 } else {
108 None
109 }
110 }
111}
112unsafe impl<T> VulkanSinkStructure for &'_ mut T
113where
114 T: VulkanSinkStructure,
115{
116 #[inline(always)]
117 fn as_generic(&self) -> &GenericVulkanSinkStructure {
118 T::as_generic(*self)
119 }
120
121 #[inline(always)]
122 fn as_generic_mut(&mut self) -> &mut GenericVulkanSinkStructure {
123 T::as_generic_mut(*self)
124 }
125}
126unsafe impl<T> TypedVulkanSinkStructure for &'_ mut T
127where
128 T: TypedVulkanSinkStructure,
129{
130 const TYPE: crate::vk::VkStructureType = T::TYPE;
131}
132unsafe impl<T> VulkanSinkStructure for Box<T>
133where
134 T: VulkanSinkStructure + ?Sized,
135{
136 #[inline(always)]
137 fn as_generic(&self) -> &GenericVulkanSinkStructure {
138 T::as_generic(&*self)
139 }
140
141 #[inline(always)]
142 fn as_generic_mut(&mut self) -> &mut GenericVulkanSinkStructure {
143 T::as_generic_mut(&mut *self)
144 }
145}
146unsafe impl<T> TypedVulkanSinkStructure for Box<T>
147where
148 T: TypedVulkanSinkStructure,
149{
150 const TYPE: crate::vk::VkStructureType = T::TYPE;
151}
152
153pub struct StructureChainIterator<'a> {
154 pub(crate) current: *const GenericVulkanStructure,
155 pub(crate) marker: std::marker::PhantomData<&'a GenericVulkanStructure>,
156}
157impl<'a> Iterator for StructureChainIterator<'a> {
158 type Item = &'a GenericVulkanStructure;
159 fn next(&mut self) -> Option<&'a GenericVulkanStructure> {
160 if let Some(r) = unsafe { self.current.as_ref() } {
161 self.current = r.pNext as _;
162 unsafe { self.current.as_ref() }
163 } else {
164 None
165 }
166 }
167}
168impl FusedIterator for StructureChainIterator<'_> {}
169
170pub struct SinkStructureChainIterator<'a> {
171 pub(crate) current: *const GenericVulkanSinkStructure,
172 pub(crate) marker: core::marker::PhantomData<&'a GenericVulkanSinkStructure>,
173}
174impl<'a> Iterator for SinkStructureChainIterator<'a> {
175 type Item = &'a GenericVulkanSinkStructure;
176
177 fn next(&mut self) -> Option<&'a GenericVulkanSinkStructure> {
178 let Some(r) = (unsafe { self.current.as_ref() }) else {
179 return None;
180 };
181
182 self.current = r.pNext as _;
183 unsafe { self.current.as_ref() }
184 }
185}
186impl FusedIterator for SinkStructureChainIterator<'_> {}
187
188pub trait VulkanStructureProvider {
189 type RootStructure;
190
191 fn build<'r, 's: 'r>(&'s mut self, root: &'s mut Self::RootStructure) -> &'r mut GenericVulkanStructure;
192}
193pub struct Extends<Parent: VulkanStructureProvider, T>(pub(crate) Parent, pub(crate) T);
194impl<Parent: VulkanStructureProvider, T> VulkanStructureProvider for Extends<Parent, T>
195where
196 T: TypedVulkanStructure,
197{
198 type RootStructure = Parent::RootStructure;
199
200 fn build<'r, 's: 'r>(&'s mut self, root: &'s mut Self::RootStructure) -> &'r mut GenericVulkanStructure {
201 let parent = self.0.build(root);
202 parent.pNext = &self.1 as *const _ as _;
203 self.1.as_generic_mut()
204 }
205}
206pub trait Extendable<T>: Sized + VulkanStructureProvider {
207 #[inline]
208 fn extends(self, next: T) -> Extends<Self, T> {
209 Extends(self, next)
210 }
211}
212
213pub unsafe trait UninitVulkanStructureOps {
214 fn set_next(&mut self, next: &(impl TypedVulkanStructure + ?Sized));
215}
216unsafe impl<T> UninitVulkanStructureOps for core::mem::MaybeUninit<T>
217where
218 T: TypedVulkanStructure,
219{
220 #[inline(always)]
221 fn set_next(&mut self, next: &(impl TypedVulkanStructure + ?Sized)) {
222 let p = self.as_mut_ptr() as *mut GenericVulkanStructure;
223 unsafe {
224 core::ptr::addr_of_mut!((*p).pNext).write(next.as_generic() as *const _ as _);
225 }
226 }
227}
228
229pub trait Chainable<'d, T> {
230 fn chain(&mut self, next: &'d T) -> &mut Self;
231}
232
233pub trait StructureChainQuery {
234 fn iter_chain(&self) -> StructureChainIterator;
236
237 fn query_structure_type(&self, ty: crate::vk::VkStructureType) -> Option<&GenericVulkanStructure> {
238 self.iter_chain().find(|s| s.sType == ty)
239 }
240 fn query_structure<S: TypedVulkanStructure>(&self) -> Option<&S> {
241 self.query_structure_type(S::TYPE)
242 .map(|r| unsafe { r.cast_unchecked() })
243 }
244}
245impl<S: TypedVulkanStructure> StructureChainQuery for S {
246 #[inline(always)]
247 fn iter_chain(&self) -> StructureChainIterator {
248 StructureChainIterator {
249 current: self.as_generic() as _,
250 marker: std::marker::PhantomData,
251 }
252 }
253}
254
255pub trait SinkStructureChainQuery {
256 fn iter_chain(&self) -> SinkStructureChainIterator;
258
259 #[inline(always)]
260 fn query_structure_type(&self, ty: crate::vk::VkStructureType) -> Option<&GenericVulkanSinkStructure> {
261 self.iter_chain().find(|s| s.sType == ty)
262 }
263
264 #[inline(always)]
265 fn query_structure<S: TypedVulkanSinkStructure>(&self) -> Option<&S> {
266 self.query_structure_type(S::TYPE)
267 .map(|r| unsafe { r.cast_ref_unchecked() })
268 }
269}
270impl<S: TypedVulkanSinkStructure> SinkStructureChainQuery for S {
271 #[inline(always)]
272 fn iter_chain(&self) -> SinkStructureChainIterator {
273 SinkStructureChainIterator {
274 current: self.as_generic() as _,
275 marker: core::marker::PhantomData,
276 }
277 }
278}