1#![warn(clippy::all)]
14#![cfg_attr(docsrs, feature(doc_cfg))]
15#![doc(html_root_url = "https://docs.ct2.io/bedrock/mod-peridot/")]
16
17#[cfg(feature = "VK_KHR_android_surface")]
19extern crate android;
20#[cfg(feature = "DynamicLoaded")]
21extern crate libloading;
22#[cfg(any(feature = "VK_KHR_xlib_surface", feature = "VK_EXT_acquire_xlib_display"))]
23extern crate x11;
24#[cfg(feature = "VK_KHR_xcb_surface")]
25extern crate xcb;
26
27#[cfg(feature = "DynamicLoaded")]
28#[cfg(unix)]
29mod libdl;
30#[cfg(feature = "DynamicLoaded")]
31#[cfg(windows)]
32mod libloaderapi;
33
34use cfg_if::cfg_if;
35use derives::*;
36
37pub use derives::SpecializationConstants;
38
39#[macro_use]
40mod vk1;
41mod vk2;
42pub mod vk {
43 pub use crate::vk1::*;
44 pub use crate::vk2::*;
45}
46use crate::vk::*;
47
48pub mod error;
49mod resolver;
50#[cfg(feature = "Implements")]
51pub use resolver::ResolverInterface;
52pub use resolver::{PFN, StaticCallable};
53
54#[cfg(feature = "Implements")]
55#[allow(dead_code)]
56pub mod vkfn;
57#[cfg(feature = "Implements")]
58pub mod vkfn_wrapper;
59
60macro_rules! DerefContainerWithGuardsBracketImpl {
61 (for $t: path { $($required: item)* }) => {
62 DerefContainerBracketImpl!(for $t { $($required)* });
63 GuardsImpl!(for $t { $($required)* });
64 }
65}
66macro_rules! DerefContainerBracketImpl {
67 (unsafe for mut $t: path { $($required: item)* }) => {
68 unsafe impl<'s, T> $t for &'s mut T where T: $t + ?Sized { $($required)* }
69 unsafe impl<T> $t for Box<T> where T: $t + ?Sized { $($required)* }
70 unsafe impl<T> $t for core::mem::ManuallyDrop<T> where T: $t { $($required)* }
71 };
72 (unsafe for $t: path { $($required: item)* }) => {
73 unsafe impl<'s, T> $t for &'s T where T: $t + ?Sized { $($required)* }
74 unsafe impl<T> $t for std::rc::Rc<T> where T: $t + ?Sized { $($required)* }
75 unsafe impl<T> $t for std::sync::Arc<T> where T: $t + ?Sized { $($required)* }
76
77 DerefContainerBracketImpl!(unsafe for mut $t { $($required)* });
78 };
79 (for mut $t: path { $($required: item)* }) => {
80 impl<'s, T> $t for &'s mut T where T: $t + ?Sized { $($required)* }
81 impl<T> $t for Box<T> where T: $t + ?Sized { $($required)* }
82 impl<T> $t for core::mem::ManuallyDrop<T> where T: $t { $($required)* }
83 };
84 (for $t: path { $($required: item)* }) => {
85 impl<'s, T> $t for &'s T where T: $t + ?Sized { $($required)* }
86 impl<T> $t for std::rc::Rc<T> where T: $t + ?Sized { $($required)* }
87 impl<T> $t for std::sync::Arc<T> where T: $t + ?Sized { $($required)* }
88
89 DerefContainerBracketImpl!(for mut $t { $($required)* });
90 };
91}
92macro_rules! GuardsImpl {
93 (for mut $t: path { $($required: item)* }) => {
94 impl<T> $t for std::cell::RefMut<'_, T> where T: $t + ?Sized { $($required)* }
95 impl<T> $t for std::sync::RwLockWriteGuard<'_, T> where T: $t + ?Sized { $($required)* }
96 impl<T> $t for std::sync::MutexGuard<'_, T> where T: $t + ?Sized { $($required)* }
97 impl<T> $t for parking_lot::MutexGuard<'_, T> where T: $t + ?Sized { $($required)* }
98 impl<T> $t for parking_lot::MappedMutexGuard<'_, T> where T: $t + ?Sized { $($required)* }
99 impl<T> $t for parking_lot::RwLockWriteGuard<'_, T> where T: $t + ?Sized { $($required)* }
100 impl<T> $t for parking_lot::MappedRwLockWriteGuard<'_, T> where T: $t + ?Sized { $($required)* }
101 };
102 (for $t: path { $($required: item)* }) => {
103 impl<T> $t for std::cell::Ref<'_, T> where T: $t + ?Sized { $($required)* }
104 impl<T> $t for std::sync::RwLockReadGuard<'_, T> where T: $t + ?Sized { $($required)* }
105 impl<T> $t for parking_lot::RwLockReadGuard<'_, T> where T: $t + ?Sized { $($required)* }
106 impl<T> $t for parking_lot::MappedRwLockReadGuard<'_, T> where T: $t + ?Sized { $($required)* }
107
108 GuardsImpl!(for mut $t { $($required)* });
109 };
110}
111macro_rules! ForwardFnPtr {
112 (deref $name: ident -> $t: ty) => {
113 #[inline(always)]
114 fn $name(&self) -> $t {
115 (**self).$name()
116 }
117 };
118}
119
120pub type Result<T> = core::result::Result<T, VkResult>;
121
122#[cfg(feature = "alloc")]
123pub(crate) mod alloc;
124
125mod handle;
126pub use self::handle::*;
127
128#[derive(Debug, Clone, Copy, PartialEq, Eq)]
130pub enum ArrayQueryResult {
131 Complete,
133 Incomplete,
135}
136
137pub trait VkObject: VkHandle {
139 const TYPE: VkObjectType;
140
141 #[implements("VK_EXT_debug_utils")]
148 fn set_name(&self, name: Option<&core::ffi::CStr>) -> crate::Result<()>
149 where
150 Self: DeviceChild<ConcreteDevice: InstanceChild<ConcreteInstance: InstanceDebugUtilsExtension>>,
151 Self::Handle: VkRawHandle,
152 {
153 self.device()
154 .set_object_name(&DebugUtilsObjectNameInfo::new(self, name))
155 }
156}
157impl<T: VkObject + ?Sized> VkObject for &'_ T {
158 const TYPE: VkObjectType = T::TYPE;
159}
160impl<T: VkObject + ?Sized> VkObject for &'_ mut T {
161 const TYPE: VkObjectType = T::TYPE;
162}
163impl<T: VkObject + ?Sized> VkObject for std::rc::Rc<T> {
164 const TYPE: VkObjectType = T::TYPE;
165}
166impl<T: VkObject + ?Sized> VkObject for std::sync::Arc<T> {
167 const TYPE: VkObjectType = T::TYPE;
168}
169impl<T: VkObject + ?Sized> VkObject for std::cell::Ref<'_, T> {
170 const TYPE: VkObjectType = T::TYPE;
171}
172impl<T: VkObject + ?Sized> VkObject for std::cell::RefMut<'_, T> {
173 const TYPE: VkObjectType = T::TYPE;
174}
175impl<T: VkObject + ?Sized> VkObject for std::sync::MutexGuard<'_, T> {
176 const TYPE: VkObjectType = T::TYPE;
177}
178
179pub trait AnalogNumRange<T> {
181 fn begin(&self) -> T;
182 fn end(&self) -> T;
183 fn count(&self) -> T
184 where
185 T: std::ops::Sub<T, Output = T> + Copy,
186 {
187 self.end() - self.begin()
188 }
189}
190impl<T> AnalogNumRange<T> for T
191where
192 T: std::ops::Add<u32, Output = T> + Copy,
193{
194 fn begin(&self) -> T {
195 *self
196 }
197 fn end(&self) -> T {
198 *self + 1
199 }
200}
201impl<T> AnalogNumRange<T> for std::ops::Range<T>
202where
203 T: Copy,
204{
205 fn begin(&self) -> T {
206 self.start
207 }
208 fn end(&self) -> T {
209 self.end
210 }
211}
212
213pub type DeviceSize = VkDeviceSize;
215pub type Extent2D = VkExtent2D;
216pub type Offset2D = VkOffset2D;
217pub type Rect2D = VkRect2D;
218pub type Viewport = VkViewport;
219pub type Extent3D = VkExtent3D;
220pub type Offset3D = VkOffset3D;
221pub type Format = VkFormat;
222
223impl Extent2D {
225 pub const fn spread1(value: u32) -> Self {
226 Self {
227 width: value,
228 height: value,
229 }
230 }
231}
232impl Extent3D {
233 pub const fn spread1(value: u32) -> Self {
234 Self {
235 width: value,
236 height: value,
237 depth: value,
238 }
239 }
240
241 pub const fn new1(width: u32) -> Self {
242 Self {
243 width,
244 height: 1,
245 depth: 1,
246 }
247 }
248
249 pub const fn new2(width: u32, height: u32) -> Self {
250 Self {
251 width,
252 height,
253 depth: 1,
254 }
255 }
256
257 pub const fn new(width: u32, height: u32, depth: u32) -> Self {
258 Self { width, height, depth }
259 }
260
261 pub const fn as_2d_ref(&self) -> &VkExtent2D {
262 unsafe { std::mem::transmute(self) }
263 }
264}
265impl Offset2D {
266 pub const fn spread1(value: i32) -> Self {
267 Self { x: value, y: value }
268 }
269}
270impl Offset3D {
271 pub const fn spread1(value: i32) -> Self {
272 Self {
273 x: value,
274 y: value,
275 z: value,
276 }
277 }
278
279 pub const fn new1(x: i32) -> Self {
280 Self { x, y: 0, z: 0 }
281 }
282
283 pub const fn new2(x: i32, y: i32) -> Self {
284 Self { x, y, z: 0 }
285 }
286
287 pub const fn new(x: i32, y: i32, z: i32) -> Self {
288 Self { x, y, z }
289 }
290
291 pub const fn as_2d_ref(&self) -> &VkOffset2D {
292 unsafe { std::mem::transmute(self) }
293 }
294}
295
296impl Extent2D {
298 pub const fn with_depth(self, depth: u32) -> Extent3D {
299 Extent3D {
300 width: self.width,
301 height: self.height,
302 depth,
303 }
304 }
305}
306impl Offset2D {
307 pub const fn with_z(self, z: i32) -> Offset3D {
308 Offset3D {
309 x: self.x,
310 y: self.y,
311 z,
312 }
313 }
314}
315impl AsRef<Extent3D> for Extent3D {
317 fn as_ref(&self) -> &Self {
318 self
319 }
320}
321impl AsRef<Extent2D> for Extent2D {
322 fn as_ref(&self) -> &Self {
323 self
324 }
325}
326impl AsRef<Offset3D> for Offset3D {
327 fn as_ref(&self) -> &Self {
328 self
329 }
330}
331impl AsRef<Offset2D> for Offset2D {
332 fn as_ref(&self) -> &Self {
333 self
334 }
335}
336
337impl AsRef<Extent2D> for Extent3D {
339 fn as_ref(&self) -> &Extent2D {
340 unsafe { core::mem::transmute(self) }
341 }
342}
343impl AsRef<Offset2D> for Offset3D {
344 fn as_ref(&self) -> &Offset2D {
345 unsafe { core::mem::transmute(self) }
346 }
347}
348
349impl From<Offset3D> for Offset2D {
351 fn from(value: Offset3D) -> Self {
352 Self { x: value.x, y: value.y }
353 }
354}
355
356impl From<Extent3D> for Extent2D {
357 fn from(value: Extent3D) -> Self {
358 Self {
359 width: value.width,
360 height: value.height,
361 }
362 }
363}
364
365impl Extent3D {
367 pub const fn wh(&self) -> Extent2D {
368 Extent2D {
369 width: self.width,
370 height: self.height,
371 }
372 }
373
374 pub const fn wd(&self) -> Extent2D {
375 Extent2D {
376 width: self.width,
377 height: self.depth,
378 }
379 }
380
381 pub const fn hw(&self) -> Extent2D {
382 Extent2D {
383 width: self.height,
384 height: self.width,
385 }
386 }
387
388 pub const fn hd(&self) -> Extent2D {
389 Extent2D {
390 width: self.height,
391 height: self.depth,
392 }
393 }
394
395 pub const fn dw(&self) -> Extent2D {
396 Extent2D {
397 width: self.depth,
398 height: self.width,
399 }
400 }
401
402 pub const fn dh(&self) -> Extent2D {
403 Extent2D {
404 width: self.depth,
405 height: self.height,
406 }
407 }
408}
409impl Offset3D {
410 pub const fn xy(&self) -> Offset2D {
411 Offset2D { x: self.x, y: self.y }
412 }
413
414 pub const fn xz(&self) -> Offset2D {
415 Offset2D { x: self.x, y: self.z }
416 }
417
418 pub const fn yx(&self) -> Offset2D {
419 Offset2D { x: self.y, y: self.x }
420 }
421
422 pub const fn yz(&self) -> Offset2D {
423 Offset2D { x: self.y, y: self.z }
424 }
425
426 pub const fn zx(&self) -> Offset2D {
427 Offset2D { x: self.z, y: self.x }
428 }
429
430 pub const fn zy(&self) -> Offset2D {
431 Offset2D { x: self.z, y: self.y }
432 }
433}
434
435impl Extent2D {
437 pub const ONE: Self = Self::spread1(1);
438}
439impl Extent3D {
440 pub const ONE: Self = Self::spread1(1);
441}
442impl Offset2D {
443 pub const ZERO: Self = Self::spread1(0);
444}
445impl Offset3D {
446 pub const ZERO: Self = Self::spread1(0);
447}
448
449impl Extent2D {
451 pub const fn into_rect(self, offset: Offset2D) -> Rect2D {
452 Rect2D { offset, extent: self }
453 }
454}
455impl From<Viewport> for Rect2D {
456 fn from(vp: Viewport) -> Self {
457 Rect2D {
458 offset: Offset2D {
459 x: vp.x as _,
460 y: vp.y as _,
461 },
462 extent: Extent2D {
463 width: vp.width as _,
464 height: vp.height as _,
465 },
466 }
467 }
468}
469impl Rect2D {
470 pub const fn make_viewport(&self, depth_range: std::ops::Range<f32>) -> Viewport {
471 Viewport {
472 x: self.offset.x as _,
473 y: self.offset.y as _,
474 width: self.extent.width as _,
475 height: self.extent.height as _,
476 minDepth: depth_range.start,
477 maxDepth: depth_range.end,
478 }
479 }
480}
481impl Viewport {
482 pub const fn from_rect_with_depth_range(rect: &Rect2D, depth_range: core::ops::Range<f32>) -> Self {
483 rect.make_viewport(depth_range)
484 }
485
486 pub const fn set_offset(&mut self, offset: &Offset2D) -> &mut Self {
487 self.x = offset.x as _;
488 self.y = offset.y as _;
489 self
490 }
491 pub const fn set_extent(&mut self, extent: &Extent2D) -> &mut Self {
492 self.width = extent.width as _;
493 self.height = extent.height as _;
494 self
495 }
496 pub const fn set_depth_range(&mut self, range: core::ops::Range<f32>) -> &mut Self {
497 self.minDepth = range.start;
498 self.maxDepth = range.end;
499 self
500 }
501}
502
503pub(crate) mod ffi_helper;
504
505mod base;
506pub use base::*;
507mod device;
508pub use device::*;
509mod sync;
510pub use sync::*;
511pub mod resources;
512pub use resources::*;
513#[macro_use]
514mod descriptor;
515pub use descriptor::*;
516mod renderpass;
517pub use self::renderpass::*;
518mod framebuffer;
519pub use framebuffer::*;
520mod shading;
521pub use shading::*;
522mod command;
523pub use command::*;
524mod surface;
525pub use surface::*;
526mod debug;
527#[allow(unused_imports)]
528pub use debug::*;
529mod ext;
530pub use self::ext::*;
531mod external;
532#[allow(unused_imports)]
533pub use external::*;
534mod batching;
535pub use self::batching::*;
536mod dependency;
537#[allow(unused_imports)]
538pub use self::dependency::*;
539mod query;
540pub use self::query::*;
541
542mod fmt;
543pub use self::fmt::*;