1use std::fmt::{Debug, Display, Formatter, Result};
2
3#[macro_export]
4macro_rules! log_trace_common {
5 (
6 $title: literal,
7 $(
8 $log_item: expr
9 ),*
10 ) => {
11 log_trace_common!(
12 trace;
13 $title,
14 $(
15 $log_item
16 ),*
17 )
18 };
19
20 (
21 $not_trace: ident;
22 $title: literal,
23 $(
24 $log_item: expr
25 ),*
26 ) => {
27 log::$not_trace!(
28 concat!(
29 $title,
30 $(
31 concat!("\n\t", stringify!($log_item), " = ", "{:?}")
32 ),*
33 ),
34 $(
35 $log_item
36 ),*
37 )
38 };
39}
40
41
42#[macro_export]
75macro_rules! debugize_struct {
76 (
77 $input: expr;
78 {
79 $(
80 $field: ident: $({ $($recursion: tt)+ } from)? $(* $([$size_target: ident])? )? $target: ident $(| { $($closure: tt)+ })?;
81 )+
82 }
83 ) => {
84 {
85 #[allow(non_camel_case_types)]
86 struct Debugizer<$($field),+> {
87 $($field: $field),+
88 }
89 #[allow(non_camel_case_types)]
90 impl<$($field: std::fmt::Debug),+> std::fmt::Debug for Debugizer<$($field),+> {
91 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
92 f.debug_struct("")
93 $(
94 .field(stringify!($field), &self.$field)
95 )+
96 .finish()
97 }
98 }
99
100 Debugizer {
101 $(
102 $field: $crate::debugize_struct!(
103 $input;
104 : $({ $($recursion)+ } from)? $(* $([$size_target])? )? $target $(| { $($closure)+ } )?
105 )
106 ),+
107 }
108 }
109 };
110
111 (
113 $input: expr;
114 : { $($recursion: tt)+ } from $target: ident
115 ) => {
116 $crate::debugize_struct!(
117 $input.$target;
118 {
119 $($recursion)+
120 }
121 )
122 };
123
124 (
125 $input: expr;
126 : { $($recursion: tt)+ } from *$target: ident
127 ) => {
128 $crate::debugize_struct!($input; : *$target).map(
129 |r| {
130 $crate::debugize_struct!(
131 r;
132 {
133 $($recursion)+
134 }
135 )
136 }
137 )
138 };
139
140 (
141 $input: expr;
142 : { $($recursion: tt)+ } from *[$size_target: ident] $target: ident
143 ) => {
144 $crate::debugize_struct!($input; : *[$size_target] $target).map(
145 |s| s.iter().map(|e| {
146 $crate::debugize_struct!(
147 e;
148 {
149 $($recursion)+
150 }
151 )
152 }
153 ).collect::<Vec<_>>()
154 )
155 };
156
157 (
159 $input: expr;
160 : $target: ident | { $($closure: tt)+ }
161 ) => {
162 (|$target| { $($closure)+ })($input.$target)
163 };
164
165 (
167 $input: expr;
168 : *[$size_target: ident] $target: ident
169 ) => {
170 $input.$target.as_ref().map(|r| std::slice::from_raw_parts(r, $input.$size_target as usize))
171 };
172
173 (
175 $input: expr;
176 : *$target: ident
177 ) => {
178 $input.$target.as_ref()
179 };
180
181 (
183 $input: expr;
184 : $target: ident
185 ) => {
186 $input.$target
187 };
188}
189
190pub fn log_vulkayes_debug_info() {
191 log::debug!(
192 "Enabled features:
193 host_allocator: {}
194 rust_host_allocator: {}
195 naive_device_allocator: {}
196 multi_thread: {}
197 insecure_hash: {}
198 runtime_implicit_validations: {}
199 vulkan1_1: {}
200 vulkan1_2: {}
201",
202 cfg!(feature = "host_allocator"),
203 cfg!(feature = "rust_host_allocator"),
204 cfg!(feature = "naive_device_allocator"),
205 cfg!(feature = "multi_thread"),
206 cfg!(feature = "insecure_hash"),
207 cfg!(feature = "runtime_implicit_validations"),
208 cfg!(feature = "vulkan1_1"),
209 cfg!(feature = "vulkan1_2"),
210 );
211}
212
213pub fn format_handle<H: ash::vk::Handle>(handle: H) -> impl Debug + Display {
215 struct Inner {
216 ty: ash::vk::ObjectType,
217 raw: u64
218 }
219 impl Debug for Inner {
220 fn fmt(&self, f: &mut Formatter) -> Result {
221 write!(f, "<{:?} 0x{:x}>", self.ty, self.raw)
222 }
223 }
224 impl Display for Inner {
225 fn fmt(&self, f: &mut Formatter) -> Result {
226 write!(f, "<{:?} 0x{:x}>", self.ty, self.raw)
227 }
228 }
229
230 Inner {
231 ty: H::TYPE,
232 raw: handle.as_raw()
233 }
234}
235
236#[repr(transparent)]
237#[derive(Clone, Copy, Default)]
238pub struct VkVersion(pub u32);
239impl VkVersion {
240 pub fn new(major: u32, minor: u32, patch: u32) -> Self {
241 VkVersion(ash::vk::make_version(major, minor, patch))
242 }
243}
244impl Debug for VkVersion {
245 fn fmt(&self, f: &mut Formatter) -> Result {
246 <VkVersion as Display>::fmt(self, f)
247 }
248}
249impl Display for VkVersion {
250 fn fmt(&self, f: &mut Formatter) -> Result {
251 write!(
252 f,
253 "v{}.{}.{}",
254 ash::vk::version_major(self.0),
255 ash::vk::version_minor(self.0),
256 ash::vk::version_patch(self.0)
257 )
258 }
259}
260impl From<u32> for VkVersion {
261 fn from(v: u32) -> Self {
262 VkVersion(v)
263 }
264}
265
266pub fn format_uuid(uuid: [u8; 16]) -> impl Debug + Display {
268 struct Inner {
269 uuid: [u8; 16]
270 }
271 impl Debug for Inner {
272 fn fmt(&self, f: &mut Formatter) -> Result {
273 write!(
274 f,
275 "{:0>2x}{:0>2x}{:0>2x}{:0>2x}-{:0>2x}{:0>2x}-{:0>2x}{:0>2x}-{:0>2x}{:0>2x}-{:0>2x}{:0>2x}{:0>2x}{:0>2x}{:0>2x}{:0>2x}",
276 self.uuid[0], self.uuid[1], self.uuid[2], self.uuid[3],
277 self.uuid[4], self.uuid[5],
278 self.uuid[6], self.uuid[7],
279 self.uuid[8], self.uuid[9],
280 self.uuid[10], self.uuid[11], self.uuid[12], self.uuid[13], self.uuid[14], self.uuid[15]
281 )
282 }
283 }
284 impl Display for Inner {
285 fn fmt(&self, f: &mut Formatter) -> Result {
286 write!(
287 f,
288 "{:x}{:x}{:x}{:x}-{:x}{:x}-{:x}{:X}-{:x}{:x}-{:x}{:x}{:x}{:x}{:x}{:x}",
289 self.uuid[0],
290 self.uuid[1],
291 self.uuid[2],
292 self.uuid[3],
293 self.uuid[4],
294 self.uuid[5],
295 self.uuid[6],
296 self.uuid[7],
297 self.uuid[8],
298 self.uuid[9],
299 self.uuid[10],
300 self.uuid[11],
301 self.uuid[12],
302 self.uuid[13],
303 self.uuid[14],
304 self.uuid[15]
305 )
306 }
307 }
308
309 Inner { uuid }
310}