1use crate::ffi_helper::slice_as_ptr_empty_null;
2use crate::*;
3use derives::{bitflags_newtype, implements};
4
5pub trait Image: VkHandle<Handle = VkImage> + DeviceChildHandle {
6 fn format(&self) -> VkFormat;
8
9 fn size(&self) -> &VkExtent3D;
11
12 fn dimension(&self) -> VkImageViewType;
13
14 #[implements]
16 #[inline]
17 fn sparse_requirement_count(&self) -> u32 {
18 let mut n = 0;
19 unsafe {
20 crate::vkfn::get_image_sparse_memory_requirements(
21 self.device_handle(),
22 self.native_ptr(),
23 &mut n,
24 core::ptr::null_mut(),
25 );
26 }
27
28 n
29 }
30
31 #[implements]
33 #[inline]
34 fn sparse_requirements(&self, sink: &mut [core::mem::MaybeUninit<VkSparseImageMemoryRequirements>]) -> u32 {
35 let mut n = sink.len() as _;
36 unsafe {
37 crate::vkfn::get_image_sparse_memory_requirements(
38 self.device_handle(),
39 self.native_ptr(),
40 &mut n,
41 sink.as_mut_ptr() as _,
42 );
43 }
44
45 n
46 }
47
48 #[implements("alloc")]
50 fn sparse_requirements_alloc(&self) -> Vec<VkSparseImageMemoryRequirements> {
51 let n = self.sparse_requirement_count() as usize;
52 if n == 0 {
53 return crate::alloc::empty_sink_buffer();
55 }
56
57 let mut xs = Vec::with_capacity(n);
58 let n = self.sparse_requirements(xs.spare_capacity_mut()) as usize;
59 unsafe {
60 xs.set_len(n);
61 }
62
63 xs
64 }
65
66 #[implements]
68 fn layout_info(&self, subresource: &ImageSubresource) -> VkSubresourceLayout {
69 let mut s = core::mem::MaybeUninit::uninit();
70 unsafe {
71 crate::vkfn::get_image_subresource_layout(
72 self.device_handle(),
73 self.native_ptr(),
74 subresource,
75 s.as_mut_ptr(),
76 );
77
78 s.assume_init()
79 }
80 }
81
82 #[inline]
83 fn memory_barrier(&self, subresource_range: ImageSubresourceRange, trans: LayoutTransition) -> ImageMemoryBarrier {
84 ImageMemoryBarrier::new(self, subresource_range, trans)
85 }
86
87 #[cfg(feature = "VK_KHR_synchronization2")]
88 #[inline]
89 fn memory_barrier2<'r>(&'r self, subresource_range: ImageSubresourceRange) -> crate::ImageMemoryBarrier2<'r> {
90 crate::ImageMemoryBarrier2::new(self, subresource_range)
91 }
92
93 #[implements("VK_EXT_image_drm_format_modifier")]
95 #[inline]
96 unsafe fn drm_format_modifier_properties_raw(
97 &self,
98 sink: &mut core::mem::MaybeUninit<VkImageDrmFormatModifierPropertiesEXT>,
99 ) -> crate::Result<()>
100 where
101 Self: DeviceChild<ConcreteDevice: DeviceImageDrmFormatModifierExtension>,
102 {
103 use crate::Device;
104
105 self.device().get_image_drm_format_modifier_properties_ext_fn().0(
106 self.device_handle(),
107 self.native_ptr(),
108 sink.as_mut_ptr(),
109 )
110 .into_result()
111 .map(drop)
112 }
113
114 #[implements("VK_EXT_image_drm_format_modifier")]
116 fn drm_format_modifier_properties(&self) -> crate::Result<VkImageDrmFormatModifierPropertiesEXT>
117 where
118 Self: DeviceChild<ConcreteDevice: DeviceImageDrmFormatModifierExtension>,
119 {
120 let mut properties = core::mem::MaybeUninit::<VkImageDrmFormatModifierPropertiesEXT>::uninit();
121 unsafe {
122 let p = properties.as_mut_ptr();
123 core::ptr::addr_of_mut!((*p).sType).write(VkImageDrmFormatModifierPropertiesEXT::TYPE);
124 core::ptr::addr_of_mut!((*p).pNext).write(core::ptr::null_mut());
125
126 self.drm_format_modifier_properties_raw(&mut properties)?;
127
128 Ok(properties.assume_init())
129 }
130 }
131}
132DerefContainerBracketImpl!(for Image {
133 fn format(&self) -> VkFormat {
134 T::format(self)
135 }
136
137 fn size(&self) -> &VkExtent3D {
138 T::size(self)
139 }
140
141 fn dimension(&self) -> VkImageViewType {
142 T::dimension(self)
143 }
144});
145GuardsImpl!(for Image {
146 fn format(&self) -> VkFormat {
147 T::format(&self)
148 }
149
150 fn size(&self) -> &VkExtent3D {
151 T::size(&self)
152 }
153
154 fn dimension(&self) -> VkImageViewType {
155 T::dimension(&self)
156 }
157});
158
159pub trait DeviceChildImage: Image + DeviceChild {}
160impl<T: Image + DeviceChild> DeviceChildImage for T {}
161
162pub trait ImageChild {
163 type ConcreteImage: crate::Image;
164
165 fn image(&self) -> &Self::ConcreteImage;
166}
167DerefContainerBracketImpl!(for ImageChild {
168 type ConcreteImage = T::ConcreteImage;
169
170 #[inline(always)]
171 fn image(&self) -> &Self::ConcreteImage { T::image(self) }
172});
173GuardsImpl!(for ImageChild {
174 type ConcreteImage = T::ConcreteImage;
175
176 #[inline(always)]
177 fn image(&self) -> &Self::ConcreteImage { T::image(&self) }
178});
179
180pub trait ImageChildMut: ImageChild {
181 fn image_mut(&mut self) -> &mut Self::ConcreteImage;
182}
183DerefContainerBracketImpl!(for mut ImageChildMut {
184 #[inline(always)]
185 fn image_mut(&mut self) -> &mut Self::ConcreteImage {
186 T::image_mut(self)
187 }
188});
189GuardsImpl!(for mut ImageChildMut {
190 #[inline(always)]
191 fn image_mut(&mut self) -> &mut Self::ConcreteImage {
192 T::image_mut(self)
193 }
194});
195
196pub trait ImageView: VkHandle<Handle = VkImageView> {}
197DerefContainerBracketImpl!(for ImageView {});
198GuardsImpl!(for ImageView {});
199
200pub trait ConcreteDeviceImageView: ImageView + DeviceChild {}
201DerefContainerBracketImpl!(for ConcreteDeviceImageView {});
202GuardsImpl!(for ConcreteDeviceImageView {});
203
204pub trait ImageSize {
206 const DIMENSION: VkImageType;
207
208 fn conv(self) -> VkExtent3D;
209}
210impl ImageSize for u32 {
211 const DIMENSION: VkImageType = VK_IMAGE_TYPE_1D;
212
213 fn conv(self) -> VkExtent3D {
214 VkExtent3D {
215 width: self,
216 height: 1,
217 depth: 1,
218 }
219 }
220}
221impl ImageSize for VkExtent2D {
222 const DIMENSION: VkImageType = VK_IMAGE_TYPE_2D;
223
224 fn conv(self) -> VkExtent3D {
225 self.with_depth(1)
226 }
227}
228impl ImageSize for VkExtent3D {
229 const DIMENSION: VkImageType = VK_IMAGE_TYPE_3D;
230
231 fn conv(self) -> VkExtent3D {
232 self
233 }
234}
235
236#[derive(VkHandle, VkObject)]
238#[VkObject(type = VkImage::OBJECT_TYPE)]
239pub struct ImageObject<Device: VkHandle<Handle = VkDevice>>(VkImage, Device, VkImageType, VkFormat, VkExtent3D);
240#[implements]
241impl<Device: VkHandle<Handle = VkDevice>> Drop for ImageObject<Device> {
242 #[inline(always)]
243 fn drop(&mut self) {
244 unsafe {
245 crate::vkfn::destroy_image(self.1.native_ptr(), self.0, core::ptr::null());
246 }
247 }
248}
249unsafe impl<Device: VkHandle<Handle = VkDevice> + Sync> Sync for ImageObject<Device> {}
250unsafe impl<Device: VkHandle<Handle = VkDevice> + Send> Send for ImageObject<Device> {}
251impl<Device: VkHandle<Handle = VkDevice>> DeviceChildHandle for ImageObject<Device> {
252 #[inline(always)]
253 fn device_handle(&self) -> VkDevice {
254 self.1.native_ptr()
255 }
256}
257impl<Device: crate::Device> DeviceChild for ImageObject<Device> {
258 type ConcreteDevice = Device;
259
260 #[inline(always)]
261 fn device(&self) -> &Self::ConcreteDevice {
262 &self.1
263 }
264}
265impl<Device: VkHandle<Handle = VkDevice>> Image for ImageObject<Device> {
266 fn format(&self) -> VkFormat {
267 self.3
268 }
269
270 fn size(&self) -> &VkExtent3D {
271 &self.4
272 }
273
274 fn dimension(&self) -> VkImageViewType {
275 match self.2 {
276 VK_IMAGE_TYPE_1D => VK_IMAGE_VIEW_TYPE_1D,
277 VK_IMAGE_TYPE_2D => VK_IMAGE_VIEW_TYPE_2D,
278 VK_IMAGE_TYPE_3D => VK_IMAGE_VIEW_TYPE_3D,
279 _ => unreachable!(),
280 }
281 }
282}
283impl<Device: VkHandle<Handle = VkDevice>> MemoryBound for ImageObject<Device> {
284 #[cfg(feature = "VK_KHR_get_memory_requirements2")]
285 type MemoryRequirementsInfo2<'b>
286 = ImageMemoryRequirementsInfo2<'b, Self>
287 where
288 Device: 'b;
289
290 #[implements]
291 fn requirements(&self) -> VkMemoryRequirements {
292 let mut p = core::mem::MaybeUninit::uninit();
293 unsafe {
294 crate::vkfn::get_image_memory_requirements(self.1.native_ptr(), self.0, p.as_mut_ptr());
295
296 p.assume_init()
297 }
298 }
299
300 #[cfg(feature = "VK_KHR_get_memory_requirements2")]
301 fn requirements2<'b>(&'b self) -> Self::MemoryRequirementsInfo2<'b> {
302 ImageMemoryRequirementsInfo2::new(self)
303 }
304
305 #[inline(always)]
306 #[implements]
307 fn bind(&mut self, memory: &(impl VkHandle<Handle = VkDeviceMemory> + ?Sized), offset: usize) -> crate::Result<()>
308 where
309 Self: VkHandleMut,
310 {
311 unsafe {
312 crate::vkfn::bind_image_memory(self.1.native_ptr(), self.0, memory.native_ptr(), offset as _)
313 .into_result()
314 .map(drop)
315 }
316 }
317}
318impl<Device: VkHandle<Handle = VkDevice>> ImageObject<Device> {
319 pub const unsafe fn manage(
323 handle: VkImage,
324 parent: Device,
325 image_type: VkImageType,
326 format: VkFormat,
327 extent: VkExtent3D,
328 ) -> Self {
329 Self(handle, parent, image_type, format, extent)
330 }
331
332 pub const fn unmanage(self) -> (VkImage, Device, VkImageType, VkFormat, VkExtent3D) {
334 let v = self.0;
335 let p = unsafe { core::ptr::read(&self.1) };
336 let (t, f, x) = (self.2, self.3, self.4);
337 core::mem::forget(self);
338
339 (v, p, t, f, x)
340 }
341}
342impl<Device: VkHandle<Handle = VkDevice> + Clone> ImageObject<&'_ Device> {
343 #[inline(always)]
345 pub fn clone_parent(self) -> ImageObject<Device> {
346 let r = ImageObject(self.0, self.1.clone(), self.2, self.3, self.4);
347 core::mem::forget(self);
348
349 r
350 }
351}
352impl<Device: crate::Device> ImageObject<Device> {
353 #[implements]
362 #[inline]
363 pub fn new(device: Device, info: &ImageCreateInfo) -> crate::Result<Self> {
364 Ok(unsafe {
365 Self::manage(
366 device.new_image_raw(info, None)?,
367 device,
368 info.0.imageType,
369 info.0.format,
370 info.0.extent,
371 )
372 })
373 }
374}
375
376#[repr(transparent)]
377#[derive(Clone)]
378pub struct ImageCreateInfo<'d>(
379 VkImageCreateInfo,
380 core::marker::PhantomData<(Option<&'d dyn VulkanStructure>, Option<&'d [u32]>)>,
381);
382impl<'d> ImageCreateInfo<'d> {
383 #[inline(always)]
384 pub fn new<Size: ImageSize>(size: Size, format: VkFormat) -> Self {
385 Self(
386 VkImageCreateInfo {
387 sType: VkImageCreateInfo::TYPE,
388 pNext: core::ptr::null(),
389 flags: 0,
390 imageType: Size::DIMENSION,
391 extent: size.conv(),
392 format,
393 usage: 0,
394 mipLevels: 1,
395 arrayLayers: 1,
396 samples: 1,
397 initialLayout: VK_IMAGE_LAYOUT_UNDEFINED,
398 tiling: VK_IMAGE_TILING_OPTIMAL,
399 sharingMode: VK_SHARING_MODE_EXCLUSIVE,
400 queueFamilyIndexCount: 0,
401 pQueueFamilyIndices: core::ptr::null(),
402 },
403 core::marker::PhantomData,
404 )
405 }
406
407 pub const unsafe fn from_raw(raw: VkImageCreateInfo) -> Self {
408 Self(raw, core::marker::PhantomData)
409 }
410
411 pub const fn into_raw(self) -> VkImageCreateInfo {
412 self.0
413 }
414
415 #[inline(always)]
416 pub fn with_next(mut self, next: &'d (impl TypedVulkanStructure + ?Sized)) -> Self {
417 self.0.pNext = next.as_generic() as *const _ as _;
418 self
419 }
420
421 #[inline(always)]
423 pub fn size<Size: ImageSize>(mut self, size: Size) -> Self {
424 self.0.extent = size.conv();
425 self.0.imageType = Size::DIMENSION;
426
427 self
428 }
429
430 pub const fn init_layout(mut self, layout: ImageLayout) -> Self {
433 self.0.initialLayout = layout as _;
434 self
435 }
436
437 pub const fn sharing_queue_families(mut self, indices: &'d [u32]) -> Self {
440 self.0.sharingMode = if indices.is_empty() {
441 VK_SHARING_MODE_EXCLUSIVE
442 } else {
443 VK_SHARING_MODE_CONCURRENT
444 };
445 self.0.queueFamilyIndexCount = indices.len() as _;
446 self.0.pQueueFamilyIndices = slice_as_ptr_empty_null(indices);
447
448 self
449 }
450
451 pub const fn sample_counts(mut self, count_bits: u32) -> Self {
454 self.0.samples = count_bits;
455 self
456 }
457
458 pub const fn use_linear_tiling(mut self) -> Self {
461 self.0.tiling = VK_IMAGE_TILING_LINEAR;
462 self
463 }
464
465 pub const fn flags(mut self, opt: ImageFlags) -> Self {
468 self.0.flags = opt.0;
469 self
470 }
471
472 pub const fn array_layers(mut self, layers: u32) -> Self {
475 self.0.arrayLayers = layers;
476 self
477 }
478
479 pub const fn mip_levels(mut self, levels: u32) -> Self {
482 self.0.mipLevels = levels;
483 self
484 }
485
486 pub const fn with_usage(mut self, bits: ImageUsageFlags) -> Self {
488 self.0.usage |= bits.0;
489 self
490 }
491
492 pub const fn set_usage(mut self, bits: ImageUsageFlags) -> Self {
494 self.0.usage = bits.0;
495 self
496 }
497}
498impl AsRef<VkImageCreateInfo> for ImageCreateInfo<'_> {
499 #[inline(always)]
500 fn as_ref(&self) -> &VkImageCreateInfo {
501 &self.0
502 }
503}
504
505#[cfg(feature = "VK_KHR_get_memory_requirements2")]
506pub struct ImageMemoryRequirementsInfo2<'b, Image: VkHandle<Handle = VkImage> + 'b>(
507 VkImageMemoryRequirementsInfo2KHR,
508 &'b Image,
509);
510#[cfg(feature = "VK_KHR_get_memory_requirements2")]
511impl<'b, Image: VkHandle<Handle = VkImage> + 'b> ImageMemoryRequirementsInfo2<'b, Image> {
512 pub fn new(image: &'b Image) -> Self {
513 Self(
514 VkImageMemoryRequirementsInfo2KHR {
515 sType: VkImageMemoryRequirementsInfo2KHR::TYPE,
516 pNext: core::ptr::null(),
517 image: image.native_ptr(),
518 },
519 image,
520 )
521 }
522
523 #[implements("Allow1_1APIs")]
524 pub fn query(self, sink: &mut core::mem::MaybeUninit<VkMemoryRequirements2KHR>)
525 where
526 Image: crate::DeviceChild,
527 {
528 unsafe {
529 crate::vkfn::get_image_memory_requirements2(self.1.device().native_ptr(), &self.0, sink.as_mut_ptr());
530 }
531 }
532}
533#[cfg(feature = "VK_KHR_get_memory_requirements2")]
534impl<Image: VkHandle<Handle = VkImage>> AsRef<VkImageMemoryRequirementsInfo2KHR>
535 for ImageMemoryRequirementsInfo2<'_, Image>
536{
537 fn as_ref(&self) -> &VkImageMemoryRequirementsInfo2KHR {
538 &self.0
539 }
540}
541
542#[cfg(feature = "VK_KHR_bind_memory2")]
543#[repr(transparent)]
544pub struct BindImageMemoryInfo<'b>(
545 VkBindImageMemoryInfoKHR,
546 core::marker::PhantomData<(VkHandleRef<'b, VkImage>, VkHandleRef<'b, VkDeviceMemory>)>,
547);
548#[cfg(feature = "VK_KHR_bind_memory2")]
549impl<'b> BindImageMemoryInfo<'b> {
550 pub fn new(
551 image: &'b (impl VkHandle<Handle = VkImage> + ?Sized),
552 memory: &'b (impl VkHandle<Handle = VkDeviceMemory> + ?Sized),
553 offset: DeviceSize,
554 ) -> Self {
555 Self(
556 VkBindImageMemoryInfoKHR {
557 sType: VkBindImageMemoryInfoKHR::TYPE,
558 pNext: core::ptr::null(),
559 image: image.native_ptr(),
560 memory: memory.native_ptr(),
561 memoryOffset: offset,
562 },
563 core::marker::PhantomData,
564 )
565 }
566
567 pub const unsafe fn from_raw(raw: VkBindImageMemoryInfoKHR) -> Self {
568 Self(raw, core::marker::PhantomData)
569 }
570
571 pub const fn into_raw(self) -> VkBindImageMemoryInfoKHR {
572 self.0
573 }
574}
575
576#[repr(u32)]
578#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
579pub enum ImageLayout {
580 Undefined = VK_IMAGE_LAYOUT_UNDEFINED as _,
582 Preinitialized = VK_IMAGE_LAYOUT_PREINITIALIZED as _,
584 General = VK_IMAGE_LAYOUT_GENERAL as _,
586 ColorAttachmentOpt = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL as _,
588 DepthStencilAttachmentOpt = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL as _,
590 DepthStencilReadOnlyOpt = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL as _,
594 ShaderReadOnlyOpt = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL as _,
597 TransferSrcOpt = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL as _,
599 TransferDestOpt = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL as _,
601 #[cfg(feature = "VK_KHR_swapchain")]
603 PresentSrc = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR as _,
604}
605impl ImageLayout {
606 pub fn default_access_mask(self) -> VkAccessFlags {
608 match self {
609 Self::Undefined | Self::Preinitialized => 0,
610 Self::General => VK_ACCESS_MEMORY_READ_BIT,
611 Self::ColorAttachmentOpt => VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
612 Self::DepthStencilAttachmentOpt => VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
613 Self::DepthStencilReadOnlyOpt => VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
614 Self::ShaderReadOnlyOpt => VK_ACCESS_SHADER_READ_BIT,
615 Self::TransferSrcOpt => VK_ACCESS_TRANSFER_READ_BIT,
616 Self::TransferDestOpt => VK_ACCESS_TRANSFER_WRITE_BIT,
617 #[cfg(feature = "VK_KHR_swapchain")]
618 Self::PresentSrc => VK_ACCESS_MEMORY_READ_BIT,
619 }
620 }
621
622 #[inline(always)]
624 pub const fn to(self, after: Self) -> LayoutTransition {
625 LayoutTransition { from: self, to: after }
626 }
627 #[inline(always)]
629 pub const fn from(self, before: Self) -> LayoutTransition {
630 LayoutTransition { from: before, to: self }
631 }
632 #[inline(always)]
634 pub const fn from_undefined(self) -> LayoutTransition {
635 self.from(Self::Undefined)
636 }
637
638 #[inline(always)]
640 pub const fn keep(self) -> LayoutTransition {
641 LayoutTransition { from: self, to: self }
642 }
643}
644
645#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
647pub struct LayoutTransition {
648 pub from: ImageLayout,
649 pub to: ImageLayout,
650}
651
652#[derive(Clone, Copy, PartialEq, Eq, Hash)]
654#[bitflags_newtype]
655pub struct ImageUsageFlags(VkImageUsageFlags);
656impl ImageUsageFlags {
657 pub const TRANSFER_SRC: Self = Self(VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
659 pub const TRANSFER_DEST: Self = Self(VK_IMAGE_USAGE_TRANSFER_DST_BIT);
661 pub const SAMPLED: Self = Self(VK_IMAGE_USAGE_SAMPLED_BIT);
664 pub const STORAGE: Self = Self(VK_IMAGE_USAGE_STORAGE_BIT);
666 pub const COLOR_ATTACHMENT: Self = Self(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
668 pub const DEPTH_STENCIL_ATTACHMENT: Self = Self(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
670 pub const TRANSIENT_ATTACHMENT: Self = Self(VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT);
674 pub const INPUT_ATTACHMENT: Self = Self(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
677}
678
679#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
681#[bitflags_newtype]
682pub struct ImageFlags(VkImageCreateFlags);
683impl ImageFlags {
684 pub const EMPTY: Self = Self(0);
686 pub const SPARSE_BINDING: Self = Self(VK_IMAGE_CREATE_SPARSE_BINDING_BIT);
688 pub const SPARSE_RESIDENCY: Self = Self(VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
690 pub const SPARSE_ALIASED: Self = Self(VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT);
693 pub const MUTABLE_FORMAT: Self = Self(VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT);
695 pub const CUBE_COMPATIBLE: Self = Self(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT);
697}
698
699#[cfg(feature = "VK_KHR_get_memory_requirements2")]
700#[repr(transparent)]
701#[derive(Clone)]
702pub struct ImageSparseMemoryRequirementsInfo2<'r>(
703 pub(crate) VkImageSparseMemoryRequirementsInfo2KHR,
704 core::marker::PhantomData<(Option<&'r dyn VulkanStructure>, &'r dyn VkHandle<Handle = VkImage>)>,
705);
706#[cfg(feature = "VK_KHR_get_memory_requirements2")]
707impl<'r> ImageSparseMemoryRequirementsInfo2<'r> {
708 #[inline]
709 pub fn new(image: &'r (impl VkHandle<Handle = VkImage> + ?Sized)) -> Self {
710 Self(
711 VkImageSparseMemoryRequirementsInfo2KHR {
712 sType: VkImageSparseMemoryRequirementsInfo2KHR::TYPE,
713 pNext: core::ptr::null(),
714 image: image.native_ptr(),
715 },
716 core::marker::PhantomData,
717 )
718 }
719
720 pub const unsafe fn from_raw(raw: VkImageSparseMemoryRequirementsInfo2KHR) -> Self {
721 Self(raw, core::marker::PhantomData)
722 }
723
724 pub const fn into_raw(self) -> VkImageSparseMemoryRequirementsInfo2KHR {
725 self.0
726 }
727
728 #[inline]
729 pub fn with_next(mut self, next: &'r (impl VulkanStructure + ?Sized)) -> Self {
730 self.0.pNext = next.as_generic() as *const _ as _;
731 self
732 }
733}
734
735#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
737#[bitflags_newtype]
738pub struct AspectMask(VkImageAspectFlags);
739impl AspectMask {
740 pub const EMPTY: Self = Self(0);
742 pub const COLOR: Self = Self(VK_IMAGE_ASPECT_COLOR_BIT);
744 pub const DEPTH: Self = Self(VK_IMAGE_ASPECT_DEPTH_BIT);
746 pub const STENCIL: Self = Self(VK_IMAGE_ASPECT_STENCIL_BIT);
748 pub const METADATA: Self = Self(VK_IMAGE_ASPECT_METADATA_BIT);
750}
751
752pub type ImageSubresource = VkImageSubresource;
753impl ImageSubresource {
754 pub const fn new(aspect_mask: AspectMask, mip_level: u32, array_layer: u32) -> Self {
755 Self {
756 aspectMask: aspect_mask.bits(),
757 mipLevel: mip_level,
758 arrayLayer: array_layer,
759 }
760 }
761}
762
763pub type ImageSubresourceLayers = VkImageSubresourceLayers;
764impl ImageSubresourceLayers {
765 pub const fn new(aspect_mask: AspectMask, mip_level: u32, layer_range: core::ops::Range<u32>) -> Self {
766 Self {
767 aspectMask: aspect_mask.bits(),
768 mipLevel: mip_level,
769 baseArrayLayer: layer_range.start,
770 layerCount: layer_range.end - layer_range.start,
771 }
772 }
773}
774
775pub type ImageSubresourceRange = VkImageSubresourceRange;
776impl ImageSubresourceRange {
777 pub const fn new(
779 aspect_mask: AspectMask,
780 mip_range: core::ops::Range<u32>,
781 array_layer_range: core::ops::Range<u32>,
782 ) -> Self {
783 Self {
784 aspectMask: aspect_mask.bits(),
785 baseMipLevel: mip_range.start,
786 levelCount: mip_range.end - mip_range.start,
787 baseArrayLayer: array_layer_range.start,
788 layerCount: array_layer_range.end - array_layer_range.start,
789 }
790 }
791
792 pub const fn subresource(&self, mip_level_offset: u32, array_layer_offset: u32) -> ImageSubresource {
794 ImageSubresource {
795 aspectMask: self.aspectMask,
796 mipLevel: self.baseMipLevel + mip_level_offset,
797 arrayLayer: self.baseArrayLayer + array_layer_offset,
798 }
799 }
800}
801
802#[derive(VkHandle, VkObject)]
804#[VkObject(type = VkImageView::OBJECT_TYPE)]
805pub struct ImageViewObject<Image: DeviceChildHandle>(VkImageView, Image);
806#[implements]
807impl<Image: DeviceChildHandle> Drop for ImageViewObject<Image> {
808 #[inline(always)]
809 fn drop(&mut self) {
810 unsafe {
811 crate::vkfn::destroy_image_view(self.1.device_handle(), self.0, core::ptr::null());
812 }
813 }
814}
815unsafe impl<Image: DeviceChildHandle + Sync> Sync for ImageViewObject<Image> {}
816unsafe impl<Image: DeviceChildHandle + Send> Send for ImageViewObject<Image> {}
817impl<Image: DeviceChildHandle> DeviceChildHandle for ImageViewObject<Image> {
818 #[inline(always)]
819 fn device_handle(&self) -> VkDevice {
820 self.1.device_handle()
821 }
822}
823impl<Image: DeviceChild> DeviceChild for ImageViewObject<Image> {
824 type ConcreteDevice = Image::ConcreteDevice;
825
826 #[inline(always)]
827 fn device(&self) -> &Self::ConcreteDevice {
828 self.1.device()
829 }
830}
831impl<Image: self::Image> ImageChild for ImageViewObject<Image> {
832 type ConcreteImage = Image;
833
834 #[inline(always)]
835 fn image(&self) -> &Image {
836 &self.1
837 }
838}
839impl<Image: self::Image> ImageChildMut for ImageViewObject<Image> {
840 #[inline(always)]
841 fn image_mut(&mut self) -> &mut Image {
842 &mut self.1
843 }
844}
845impl<Image: DeviceChildHandle> ImageView for ImageViewObject<Image> {}
846impl<Image: DeviceChildHandle> ImageViewObject<Image> {
847 pub const unsafe fn manage(handle: VkImageView, parent: Image) -> Self {
851 Self(handle, parent)
852 }
853
854 pub const fn unmanage(self) -> (VkImageView, Image) {
856 let v = self.0;
857 let p = unsafe { core::ptr::read(&self.1) };
858 core::mem::forget(self);
859
860 (v, p)
861 }
862}
863impl<Image: DeviceChildHandle + Clone> ImageViewObject<&'_ Image> {
864 #[inline(always)]
866 pub fn clone_parent(self) -> ImageViewObject<Image> {
867 let r = ImageViewObject(self.0, self.1.clone());
868 core::mem::forget(self);
869
870 r
871 }
872}
873impl<Image: DeviceChild> ImageViewObject<Image> {
874 #[implements]
882 #[inline]
883 pub fn new(image: Image, info: &ImageViewCreateInfo) -> crate::Result<Self> {
884 use crate::Device;
885
886 Ok(unsafe { Self::manage(image.device().new_image_view_raw(info, None)?, image) })
887 }
888}
889
890#[repr(transparent)]
891#[derive(Clone)]
892pub struct ImageViewCreateInfo<'r>(
893 VkImageViewCreateInfo,
894 core::marker::PhantomData<&'r dyn VkHandle<Handle = VkImage>>,
895);
896impl<'r> ImageViewCreateInfo<'r> {
897 pub fn new(
898 source: &'r (impl VkHandle<Handle = VkImage> + ?Sized),
899 subresource_range: ImageSubresourceRange,
900 view_type: VkImageViewType,
901 format: VkFormat,
902 ) -> Self {
903 Self(
904 VkImageViewCreateInfo {
905 sType: VkImageViewCreateInfo::TYPE,
906 pNext: core::ptr::null(),
907 flags: 0,
908 image: source.native_ptr(),
909 viewType: view_type,
910 format,
911 components: VkComponentMapping {
912 r: VK_COMPONENT_SWIZZLE_R,
913 g: VK_COMPONENT_SWIZZLE_G,
914 b: VK_COMPONENT_SWIZZLE_B,
915 a: VK_COMPONENT_SWIZZLE_A,
916 },
917 subresourceRange: subresource_range,
918 },
919 core::marker::PhantomData,
920 )
921 }
922
923 pub const unsafe fn from_raw(raw: VkImageViewCreateInfo) -> Self {
924 Self(raw, core::marker::PhantomData)
925 }
926
927 pub const fn into_raw(self) -> VkImageViewCreateInfo {
928 self.0
929 }
930
931 pub const fn with_format_mutation(mut self, format: VkFormat) -> Self {
932 self.0.format = format;
933 self
934 }
935
936 pub const fn with_mapping(mut self, mapping: VkComponentMapping) -> Self {
937 self.0.components = mapping;
938 self
939 }
940
941 pub const fn with_dimension(mut self, dimension: VkImageViewType) -> Self {
942 self.0.viewType = dimension;
943 self
944 }
945}
946
947pub struct ImageViewBuilder<I: Image>(ImageViewCreateInfo<'static>, I);
948impl<I: Image> ImageViewBuilder<I> {
949 pub fn new(source: I, subresource_range: VkImageSubresourceRange) -> Self {
950 Self(
951 unsafe {
952 ImageViewCreateInfo::from_raw(VkImageViewCreateInfo {
953 sType: VkImageViewCreateInfo::TYPE,
954 pNext: core::ptr::null(),
955 flags: 0,
956 image: source.native_ptr(),
957 viewType: source.dimension(),
958 format: source.format(),
959 components: VkComponentMapping {
960 r: VK_COMPONENT_SWIZZLE_R,
961 g: VK_COMPONENT_SWIZZLE_G,
962 b: VK_COMPONENT_SWIZZLE_B,
963 a: VK_COMPONENT_SWIZZLE_A,
964 },
965 subresourceRange: subresource_range,
966 })
967 },
968 source,
969 )
970 }
971
972 pub const fn with_format_mutation(mut self, format: VkFormat) -> Self {
973 self.0 = self.0.with_format_mutation(format);
974 self
975 }
976
977 pub const fn with_mapping(mut self, mapping: VkComponentMapping) -> Self {
978 self.0 = self.0.with_mapping(mapping);
979 self
980 }
981
982 pub const fn with_dimension(mut self, dimension: VkImageViewType) -> Self {
983 self.0 = self.0.with_dimension(dimension);
984 self
985 }
986
987 #[implements]
995 pub fn create(self) -> crate::Result<ImageViewObject<I>>
996 where
997 I: DeviceChild,
998 {
999 ImageViewObject::new(self.1, &self.0)
1000 }
1001}