Skip to main content

bedrock_vk/
lib.rs

1mod bindings;
2pub use bindings::*;
3
4#[cfg(feature = "Implements")]
5pub mod fns;
6#[cfg(feature = "Implements")]
7mod resolver;
8#[cfg(feature = "CustomResolver")]
9pub use resolver::set_resolver;
10#[cfg(feature = "Implements")]
11pub use resolver::{ResolvedFnCell, ResolverInterface, load_function_unconstrainted, load_symbol_unconstrainted};
12
13mod result_str;
14pub use result_str::*;
15pub mod extensions;
16
17// ffi helper
18
19#[repr(transparent)]
20#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
21pub struct FixedCStrBuffer<const L: usize>(pub [u8; L]);
22impl<const L: usize> FixedCStrBuffer<L> {
23    pub const fn as_cstr(&self) -> Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> {
24        core::ffi::CStr::from_bytes_until_nul(&self.0)
25    }
26}
27
28/// # Safety
29///
30/// provides a safe wrapper around a raw function pointer, ensuring it is valid.
31pub unsafe trait FromPtr {
32    /// # Safety
33    ///
34    /// p must be a valid pointer to a function of type Self.
35    unsafe fn from_ptr(p: *const core::ffi::c_void) -> Self;
36}
37
38/// # Safety
39///
40/// provides a safe wrapper around a raw function pointer, ensuring it is valid and callable.
41pub unsafe trait PFN {
42    const NAME_CSTR: &core::ffi::CStr;
43
44    /// # Safety
45    ///
46    /// p must be a valid function pointer of type F.
47    unsafe fn from_void_fn(p: PFN_vkVoidFunction) -> Self;
48}
49pub trait StaticCallable: PFN {
50    const STATIC: Self;
51}
52
53#[repr(C)]
54#[allow(non_snake_case)]
55pub struct GenericVulkanStructure {
56    pub sType: crate::VkStructureType,
57    pub pNext: *const core::ffi::c_void,
58    pub _rest: [u8; 0],
59}
60impl GenericVulkanStructure {
61    /// # Safety
62    ///
63    /// self must be a valid Vulkan structure type of T.
64    pub const unsafe fn cast_unchecked<T>(&self) -> &T {
65        unsafe { core::mem::transmute(self) }
66    }
67}
68
69/// Trait for Vulkan structures that can be cast to [`GenericVulkanStructure`] safely.
70///
71/// # Safety
72///
73/// self must be a valid Vulkan structure type.
74pub unsafe trait VulkanStructure {
75    /// Cast structure ref to generic. This is same as transmute but must be safe.
76    fn as_generic(&self) -> &GenericVulkanStructure;
77
78    /// Cast structure mutable ref to generic. This is same as transmute but must be safe.
79    fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure;
80}
81/// Trait for Vulkan structures that have a known [`crate::vk::VkStructureType`] at compile time.
82pub trait TypedVulkanStructure: VulkanStructure {
83    /// sType of this structure
84    const TYPE: crate::VkStructureType;
85
86    /// Cast structure ref only if sType matches
87    fn try_from_generic(g: &GenericVulkanStructure) -> Option<&Self>
88    where
89        Self: Sized,
90    {
91        if g.sType == Self::TYPE {
92            Some(unsafe { g.cast_unchecked() })
93        } else {
94            None
95        }
96    }
97}
98unsafe impl<S: VulkanStructure + ?Sized> VulkanStructure for &'_ mut S {
99    fn as_generic(&self) -> &GenericVulkanStructure {
100        S::as_generic(*self)
101    }
102
103    fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
104        S::as_generic_mut(*self)
105    }
106}
107impl<S: TypedVulkanStructure + ?Sized> TypedVulkanStructure for &'_ mut S {
108    const TYPE: crate::VkStructureType = S::TYPE;
109}
110unsafe impl<S: VulkanStructure + ?Sized> VulkanStructure for Box<S> {
111    fn as_generic(&self) -> &GenericVulkanStructure {
112        S::as_generic(&**self)
113    }
114
115    fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
116        S::as_generic_mut(&mut **self)
117    }
118}
119impl<S: TypedVulkanStructure + ?Sized> TypedVulkanStructure for Box<S> {
120    const TYPE: crate::VkStructureType = S::TYPE;
121}
122
123#[repr(C)]
124#[allow(non_snake_case)]
125pub struct GenericVulkanSinkStructure {
126    pub sType: crate::VkStructureType,
127    pub pNext: *mut core::ffi::c_void,
128    _rest: [u8; 0],
129}
130impl GenericVulkanSinkStructure {
131    /// # Safety
132    ///
133    /// self must be a valid Vulkan structure type of T.
134    pub const unsafe fn cast_ref_unchecked<T>(&self) -> &T {
135        unsafe { core::mem::transmute(self) }
136    }
137
138    /// # Safety
139    ///
140    /// self must be a valid Vulkan structure type of T.
141    pub const unsafe fn cast_mut_unchecked<T>(&mut self) -> &mut T {
142        unsafe { core::mem::transmute(self) }
143    }
144}
145
146/// Trait for Vulkan structures that can be cast to [`GenericVulkanSinkStructure`] safely.
147///
148/// # Safety
149///
150/// self must be a valid Vulkan structure type.
151pub unsafe trait VulkanSinkStructure {
152    /// Cast this structure ref to generic one. This is same as transmute but must be safe.
153    fn as_generic(&self) -> &GenericVulkanSinkStructure;
154
155    /// Cast this structure mutable ref to generic one. This is same as transmute but must be safe.
156    fn as_generic_mut(&mut self) -> &mut GenericVulkanSinkStructure;
157}
158/// Trait for Vulkan structures that have a known [`crate::vk::VkStructureType`] at compile time.
159pub trait TypedVulkanSinkStructure: VulkanSinkStructure {
160    /// `sType` constant for this structure.
161    const TYPE: crate::VkStructureType;
162
163    /// Constructs an uninitialized cell for this structure, that is ready to pass the api
164    fn uninit_sink() -> core::mem::MaybeUninit<Self>
165    where
166        Self: Sized,
167    {
168        let mut p = core::mem::MaybeUninit::<Self>::uninit();
169        unsafe {
170            let ptr = p.as_mut_ptr().cast::<GenericVulkanSinkStructure>();
171            core::ptr::addr_of_mut!((*ptr).sType).write(Self::TYPE);
172            core::ptr::addr_of_mut!((*ptr).pNext).write(core::ptr::null_mut());
173        }
174
175        p
176    }
177
178    /// Cast structure ref only if sType matches
179    fn try_from_generic(g: &GenericVulkanSinkStructure) -> Option<&Self>
180    where
181        Self: Sized,
182    {
183        if g.sType == Self::TYPE {
184            Some(unsafe { g.cast_ref_unchecked() })
185        } else {
186            None
187        }
188    }
189}
190unsafe impl<T> VulkanSinkStructure for &'_ mut T
191where
192    T: VulkanSinkStructure,
193{
194    #[inline(always)]
195    fn as_generic(&self) -> &GenericVulkanSinkStructure {
196        T::as_generic(self)
197    }
198
199    #[inline(always)]
200    fn as_generic_mut(&mut self) -> &mut GenericVulkanSinkStructure {
201        T::as_generic_mut(self)
202    }
203}
204impl<T> TypedVulkanSinkStructure for &'_ mut T
205where
206    T: TypedVulkanSinkStructure,
207{
208    const TYPE: crate::VkStructureType = T::TYPE;
209}
210unsafe impl<T> VulkanSinkStructure for Box<T>
211where
212    T: VulkanSinkStructure + ?Sized,
213{
214    #[inline(always)]
215    fn as_generic(&self) -> &GenericVulkanSinkStructure {
216        T::as_generic(self)
217    }
218
219    #[inline(always)]
220    fn as_generic_mut(&mut self) -> &mut GenericVulkanSinkStructure {
221        T::as_generic_mut(self)
222    }
223}
224impl<T> TypedVulkanSinkStructure for Box<T>
225where
226    T: TypedVulkanSinkStructure,
227{
228    const TYPE: crate::VkStructureType = T::TYPE;
229}
230
231pub trait VkRawHandle {
232    const OBJECT_TYPE: VkObjectType;
233
234    fn raw_handle_value(&self) -> u64;
235}
236impl<T: VkRawHandle> VkRawHandle for Option<T> {
237    const OBJECT_TYPE: VkObjectType = T::OBJECT_TYPE;
238
239    #[inline(always)]
240    fn raw_handle_value(&self) -> u64 {
241        match self {
242            None => 0,
243            Some(x) => x.raw_handle_value(),
244        }
245    }
246}