1use alloc::vec::Vec;
2use core::convert::TryInto;
3use core::mem;
4use core::ptr;
5
6use crate::vk;
7pub type VkResult<T> = Result<T, vk::Result>;
8
9impl vk::Result {
10 #[inline]
11 pub fn result(self) -> VkResult<()> {
12 self.result_with_success(())
13 }
14
15 #[inline]
16 pub fn result_with_success<T>(self, v: T) -> VkResult<T> {
17 match self {
18 Self::SUCCESS => Ok(v),
19 _ => Err(self),
20 }
21 }
22
23 #[inline]
24 pub unsafe fn assume_init_on_success<T>(self, v: mem::MaybeUninit<T>) -> VkResult<T> {
25 self.result().map(move |()| v.assume_init())
26 }
27
28 #[inline]
29 pub unsafe fn set_vec_len_on_success<T>(self, mut v: Vec<T>, len: usize) -> VkResult<Vec<T>> {
30 self.result().map(move |()| {
31 v.set_len(len);
32 v
33 })
34 }
35}
36
37pub(crate) unsafe fn read_into_uninitialized_vector<N: Copy + Default + TryInto<usize>, T>(
46 f: impl Fn(&mut N, *mut T) -> vk::Result,
47) -> VkResult<Vec<T>>
48where
49 <N as TryInto<usize>>::Error: core::fmt::Debug,
50{
51 loop {
52 let mut count = N::default();
53 f(&mut count, ptr::null_mut()).result()?;
54 let mut data =
55 Vec::with_capacity(count.try_into().expect("`N` failed to convert to `usize`"));
56
57 let err_code = f(&mut count, data.as_mut_ptr());
58 if err_code != vk::Result::INCOMPLETE {
59 break err_code.set_vec_len_on_success(
60 data,
61 count.try_into().expect("`N` failed to convert to `usize`"),
62 );
63 }
64 }
65}
66
67pub(crate) unsafe fn read_into_defaulted_vector<
81 N: Copy + Default + TryInto<usize>,
82 T: Default + Clone,
83>(
84 f: impl Fn(&mut N, *mut T) -> vk::Result,
85) -> VkResult<Vec<T>>
86where
87 <N as TryInto<usize>>::Error: core::fmt::Debug,
88{
89 loop {
90 let mut count = N::default();
91 f(&mut count, ptr::null_mut()).result()?;
92 let mut data = alloc::vec![Default::default(); count.try_into().expect("`N` failed to convert to `usize`")];
93
94 let err_code = f(&mut count, data.as_mut_ptr());
95 if err_code != vk::Result::INCOMPLETE {
96 break err_code.set_vec_len_on_success(
97 data,
98 count.try_into().expect("`N` failed to convert to `usize`"),
99 );
100 }
101 }
102}
103
104#[cfg(feature = "debug")]
105pub(crate) fn debug_flags<Value: Into<u64> + Copy>(
106 f: &mut core::fmt::Formatter<'_>,
107 known: &[(Value, &'static str)],
108 value: Value,
109) -> core::fmt::Result {
110 let mut first = true;
111 let mut accum = value.into();
112 for &(bit, name) in known {
113 let bit = bit.into();
114 if bit != 0 && accum & bit == bit {
115 if !first {
116 f.write_str(" | ")?;
117 }
118 f.write_str(name)?;
119 first = false;
120 accum &= !bit;
121 }
122 }
123 if accum != 0 {
124 if !first {
125 f.write_str(" | ")?;
126 }
127 write!(f, "{accum:b}")?;
128 }
129 Ok(())
130}