1 use std::convert::TryInto;
2
3 use crate::vk;
4 pub type VkResult<T> = Result<T, vk::Result>;
5
6 impl From<vk::Result> for VkResult<()> {
from(err_code: vk::Result) -> Self7 fn from(err_code: vk::Result) -> Self {
8 err_code.result()
9 }
10 }
11
12 impl vk::Result {
result(self) -> VkResult<()>13 pub fn result(self) -> VkResult<()> {
14 self.result_with_success(())
15 }
16
result_with_success<T>(self, v: T) -> VkResult<T>17 pub fn result_with_success<T>(self, v: T) -> VkResult<T> {
18 match self {
19 vk::Result::SUCCESS => Ok(v),
20 _ => Err(self),
21 }
22 }
23 }
24
25 /// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore,
26 /// ensuring all available data has been read into the vector.
27 ///
28 /// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available
29 /// items may change between calls; [`vk::Result::INCOMPLETE`] is returned when the count
30 /// increased (and the vector is not large enough after querying the initial size),
31 /// requiring Ash to try again.
32 ///
33 /// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
read_into_uninitialized_vector<N: Copy + Default + TryInto<usize>, T>( f: impl Fn(&mut N, *mut T) -> vk::Result, ) -> VkResult<Vec<T>> where <N as TryInto<usize>>::Error: std::fmt::Debug,34 pub(crate) unsafe fn read_into_uninitialized_vector<N: Copy + Default + TryInto<usize>, T>(
35 f: impl Fn(&mut N, *mut T) -> vk::Result,
36 ) -> VkResult<Vec<T>>
37 where
38 <N as TryInto<usize>>::Error: std::fmt::Debug,
39 {
40 loop {
41 let mut count = N::default();
42 f(&mut count, std::ptr::null_mut()).result()?;
43 let mut data =
44 Vec::with_capacity(count.try_into().expect("`N` failed to convert to `usize`"));
45
46 let err_code = f(&mut count, data.as_mut_ptr());
47 if err_code != vk::Result::INCOMPLETE {
48 data.set_len(count.try_into().expect("`N` failed to convert to `usize`"));
49 break err_code.result_with_success(data);
50 }
51 }
52 }
53
54 /// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore,
55 /// ensuring all available data has been read into the vector.
56 ///
57 /// Items in the target vector are [`default()`][`Default::default()`]-initialized which
58 /// is required for [`vk::BaseOutStructure`]-like structs where [`vk::BaseOutStructure::s_type`]
59 /// needs to be a valid type and [`vk::BaseOutStructure::p_next`] a valid or
60 /// [`null`][`std::ptr::null_mut()`] pointer.
61 ///
62 /// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available
63 /// items may change between calls; [`vk::Result::INCOMPLETE`] is returned when the count
64 /// increased (and the vector is not large enough after querying the initial size),
65 /// requiring Ash to try again.
66 ///
67 /// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
read_into_defaulted_vector< N: Copy + Default + TryInto<usize>, T: Default + Clone, >( f: impl Fn(&mut N, *mut T) -> vk::Result, ) -> VkResult<Vec<T>> where <N as TryInto<usize>>::Error: std::fmt::Debug,68 pub(crate) unsafe fn read_into_defaulted_vector<
69 N: Copy + Default + TryInto<usize>,
70 T: Default + Clone,
71 >(
72 f: impl Fn(&mut N, *mut T) -> vk::Result,
73 ) -> VkResult<Vec<T>>
74 where
75 <N as TryInto<usize>>::Error: std::fmt::Debug,
76 {
77 loop {
78 let mut count = N::default();
79 f(&mut count, std::ptr::null_mut()).result()?;
80 let mut data =
81 vec![Default::default(); count.try_into().expect("`N` failed to convert to `usize`")];
82
83 let err_code = f(&mut count, data.as_mut_ptr());
84 if err_code != vk::Result::INCOMPLETE {
85 data.set_len(count.try_into().expect("`N` failed to convert to `usize`"));
86 break err_code.result_with_success(data);
87 }
88 }
89 }
90