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 unsafe { 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 unsafe {
31 self.result().map(move |()| {
32 v.set_len(len);
33 v
34 })
35 }
36 }
37}
38
39pub(crate) unsafe fn read_into_uninitialized_vector<N: Copy + Default + TryInto<usize>, T>(
48 f: impl Fn(&mut N, *mut T) -> vk::Result,
49) -> VkResult<Vec<T>>
50where
51 <N as TryInto<usize>>::Error: core::fmt::Debug,
52{
53 unsafe {
54 loop {
55 let mut count = N::default();
56 f(&mut count, ptr::null_mut()).result()?;
57 let mut data =
58 Vec::with_capacity(count.try_into().expect("`N` failed to convert to `usize`"));
59
60 let err_code = f(&mut count, data.as_mut_ptr());
61 if err_code != vk::Result::INCOMPLETE {
62 break err_code.set_vec_len_on_success(
63 data,
64 count.try_into().expect("`N` failed to convert to `usize`"),
65 );
66 }
67 }
68 }
69}
70
71pub(crate) unsafe fn read_into_defaulted_vector<
85 N: Copy + Default + TryInto<usize>,
86 T: Default + Clone,
87>(
88 f: impl Fn(&mut N, *mut T) -> vk::Result,
89) -> VkResult<Vec<T>>
90where
91 <N as TryInto<usize>>::Error: core::fmt::Debug,
92{
93 unsafe {
94 loop {
95 let mut count = N::default();
96 f(&mut count, ptr::null_mut()).result()?;
97 let mut data = alloc::vec![Default::default(); count.try_into().expect("`N` failed to convert to `usize`")];
98
99 let err_code = f(&mut count, data.as_mut_ptr());
100 if err_code != vk::Result::INCOMPLETE {
101 break err_code.set_vec_len_on_success(
102 data,
103 count.try_into().expect("`N` failed to convert to `usize`"),
104 );
105 }
106 }
107 }
108}
109
110#[cfg(feature = "debug")]
111pub(crate) fn debug_flags<Value: Into<u64> + Copy>(
112 f: &mut core::fmt::Formatter<'_>,
113 known: &[(Value, &'static str)],
114 value: Value,
115) -> core::fmt::Result {
116 let mut first = true;
117 let mut accum = value.into();
118 for &(bit, name) in known {
119 let bit = bit.into();
120 if bit != 0 && accum & bit == bit {
121 if !first {
122 f.write_str(" | ")?;
123 }
124 f.write_str(name)?;
125 first = false;
126 accum &= !bit;
127 }
128 }
129 if accum != 0 {
130 if !first {
131 f.write_str(" | ")?;
132 }
133 write!(f, "{accum:b}")?;
134 }
135 Ok(())
136}