1use bedrock_vk as brvk;
3
4use std::iter::FusedIterator;
5
6#[inline(always)]
7pub const fn uninit_sink<T: brvk::TypedVulkanSinkStructure>() -> core::mem::MaybeUninit<T> {
8 let mut p = core::mem::MaybeUninit::<T>::uninit();
9 unsafe {
10 core::ptr::addr_of_mut!((*p.as_mut_ptr().cast::<brvk::GenericVulkanSinkStructure>()).sType).write(T::TYPE);
11 core::ptr::addr_of_mut!((*p.as_mut_ptr().cast::<brvk::GenericVulkanSinkStructure>()).pNext)
12 .write(core::ptr::null_mut());
13 }
14
15 p
16}
17
18pub struct StructureChainIterator<'a> {
19 pub(crate) current: *const brvk::GenericVulkanStructure,
20 pub(crate) marker: std::marker::PhantomData<&'a brvk::GenericVulkanStructure>,
21}
22impl<'a> Iterator for StructureChainIterator<'a> {
23 type Item = &'a brvk::GenericVulkanStructure;
24 fn next(&mut self) -> Option<&'a brvk::GenericVulkanStructure> {
25 if let Some(r) = unsafe { self.current.as_ref() } {
26 self.current = r.pNext as _;
27 unsafe { self.current.as_ref() }
28 } else {
29 None
30 }
31 }
32}
33impl FusedIterator for StructureChainIterator<'_> {}
34
35pub struct SinkStructureChainIterator<'a> {
36 pub(crate) current: *const brvk::GenericVulkanSinkStructure,
37 pub(crate) marker: core::marker::PhantomData<&'a brvk::GenericVulkanSinkStructure>,
38}
39impl<'a> Iterator for SinkStructureChainIterator<'a> {
40 type Item = &'a brvk::GenericVulkanSinkStructure;
41
42 fn next(&mut self) -> Option<&'a brvk::GenericVulkanSinkStructure> {
43 self.current = unsafe { self.current.as_ref() }?.pNext.cast();
44 unsafe { self.current.as_ref() }
45 }
46}
47impl FusedIterator for SinkStructureChainIterator<'_> {}
48
49pub trait VulkanStructureProvider {
50 type RootStructure;
51
52 fn build<'r, 's: 'r>(&'s mut self, root: &'s mut Self::RootStructure) -> &'r mut brvk::GenericVulkanStructure;
53}
54pub struct Extends<Parent: VulkanStructureProvider, T>(pub(crate) Parent, pub(crate) T);
55impl<Parent: VulkanStructureProvider, T> VulkanStructureProvider for Extends<Parent, T>
56where
57 T: brvk::TypedVulkanStructure,
58{
59 type RootStructure = Parent::RootStructure;
60
61 fn build<'r, 's: 'r>(&'s mut self, root: &'s mut Self::RootStructure) -> &'r mut brvk::GenericVulkanStructure {
62 let parent = self.0.build(root);
63 parent.pNext = &self.1 as *const _ as _;
64 self.1.as_generic_mut()
65 }
66}
67pub trait Extendable<T>: Sized + VulkanStructureProvider {
68 #[inline]
69 fn extends(self, next: T) -> Extends<Self, T> {
70 Extends(self, next)
71 }
72}
73
74pub trait Chainable<'d, T> {
91 fn chain(&mut self, next: &'d T) -> &mut Self;
92}
93
94pub trait StructureChainQuery {
95 fn iter_chain<'a>(&'a self) -> StructureChainIterator<'a>;
97
98 fn query_structure_type(&self, ty: brvk::VkStructureType) -> Option<&brvk::GenericVulkanStructure> {
99 self.iter_chain().find(|s| s.sType == ty)
100 }
101 fn query_structure<S: brvk::TypedVulkanStructure>(&self) -> Option<&S> {
102 self.query_structure_type(S::TYPE)
103 .map(|r| unsafe { r.cast_unchecked() })
104 }
105}
106impl<S: brvk::TypedVulkanStructure> StructureChainQuery for S {
107 #[inline(always)]
108 fn iter_chain<'a>(&'a self) -> StructureChainIterator<'a> {
109 StructureChainIterator {
110 current: self.as_generic() as _,
111 marker: std::marker::PhantomData,
112 }
113 }
114}
115
116pub trait SinkStructureChainQuery {
117 fn iter_chain<'a>(&'a self) -> SinkStructureChainIterator<'a>;
119
120 #[inline(always)]
121 fn query_structure_type(&self, ty: brvk::VkStructureType) -> Option<&brvk::GenericVulkanSinkStructure> {
122 self.iter_chain().find(|s| s.sType == ty)
123 }
124
125 #[inline(always)]
126 fn query_structure<S: brvk::TypedVulkanSinkStructure>(&self) -> Option<&S> {
127 self.query_structure_type(S::TYPE)
128 .map(|r| unsafe { r.cast_ref_unchecked() })
129 }
130}
131impl<S: brvk::TypedVulkanSinkStructure> SinkStructureChainQuery for S {
132 #[inline(always)]
133 fn iter_chain<'a>(&'a self) -> SinkStructureChainIterator<'a> {
134 SinkStructureChainIterator {
135 current: self.as_generic() as _,
136 marker: core::marker::PhantomData,
137 }
138 }
139}
140
141pub fn chain_structures<'x>(mut xs: impl Iterator<Item = &'x mut brvk::GenericVulkanStructure>) {
143 let Some(mut p) = xs.next() else {
144 return;
146 };
147
148 for q in xs {
149 p.pNext = core::ptr::from_mut(q).cast();
150 p = q;
151 }
152}