bedrock/resources/
image.rs

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    /// The pixel format of an image
7    fn format(&self) -> VkFormat;
8
9    /// The size of an image
10    fn size(&self) -> &VkExtent3D;
11
12    fn dimension(&self) -> VkImageViewType;
13
14    /// Query a count of the memory requirements for a sparse image
15    #[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    /// Query the memory requirements for a sparse image
32    #[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    /// Query the memory requirements for a sparse image
49    #[implements("alloc")]
50    fn sparse_requirements_alloc(&self) -> Vec<VkSparseImageMemoryRequirements> {
51        let n = self.sparse_requirement_count() as usize;
52        if n == 0 {
53            // no items
54            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    /// Retrieve information about an image subresource
67    #[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    /// Returns an image's DRM format modifier
94    #[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    /// Returns an image's DRM format modifier
115    #[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
204/// Image Dimension by corresponding extent type
205pub 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/// Opaque handle to a image object(constructed via `ImageDesc`)
237#[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    /// Constructs from raw values
320    /// # Safety
321    /// the resource must be created from the parent
322    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    /// Purges internal values (Drop will not be called for this resource)
333    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    /// Owning parent object by cloning it.
344    #[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    /// Create a new image object
354    /// # Failure
355    /// On failure, this command returns
356    ///
357    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
358    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
359    /// * [`VK_ERROR_COMPRESSION_EXHAUSTED_EXT`]
360    /// * [`VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR`]
361    #[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    /// Sets an size and a dimension of the created image.
422    #[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    /// Sets an initial layout for the created image.
431    /// default: Undefined layout
432    pub const fn init_layout(mut self, layout: ImageLayout) -> Self {
433        self.0.initialLayout = layout as _;
434        self
435    }
436
437    /// A list of queue families that will access this image,
438    /// or an empty list if no queue families can access this image simultaneously
439    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    /// The number of sub-data element samples in the image
452    /// bitmask of 1(default), 2, 4, 8, 16, 32, 64
453    pub const fn sample_counts(mut self, count_bits: u32) -> Self {
454        self.0.samples = count_bits;
455        self
456    }
457
458    /// Sets the tiling arrangement of the data elements in memory as "linear tiling"
459    /// default: optimal tiling
460    pub const fn use_linear_tiling(mut self) -> Self {
461        self.0.tiling = VK_IMAGE_TILING_LINEAR;
462        self
463    }
464
465    /// A bitmask of `ImageFlags`describing additional parameters of the image
466    /// default: none
467    pub const fn flags(mut self, opt: ImageFlags) -> Self {
468        self.0.flags = opt.0;
469        self
470    }
471
472    /// The number of layers in the image
473    /// default: 1
474    pub const fn array_layers(mut self, layers: u32) -> Self {
475        self.0.arrayLayers = layers;
476        self
477    }
478
479    /// The number of levels of detail available for minified sampling of the image
480    /// default: 1
481    pub const fn mip_levels(mut self, levels: u32) -> Self {
482        self.0.mipLevels = levels;
483        self
484    }
485
486    /// Merges some custom usage flag bits.
487    pub const fn with_usage(mut self, bits: ImageUsageFlags) -> Self {
488        self.0.usage |= bits.0;
489        self
490    }
491
492    /// Overwrites all of custom usage flag bits.
493    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/// Layouts of image and image subresources
577#[repr(u32)]
578#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
579pub enum ImageLayout {
580    /// does not support device access
581    Undefined = VK_IMAGE_LAYOUT_UNDEFINED as _,
582    /// does not support device access. host can be written to this memory immediately
583    Preinitialized = VK_IMAGE_LAYOUT_PREINITIALIZED as _,
584    /// supports all types of device access
585    General = VK_IMAGE_LAYOUT_GENERAL as _,
586    /// must only be used as a color or resolve attachment in a `Framebuffer`
587    ColorAttachmentOpt = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL as _,
588    /// must only be used as a depth/stencil attachment in a `Framebuffer`
589    DepthStencilAttachmentOpt = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL as _,
590    /// must only be used as a read-only depth/stencil attachment in a `Framebuffer`
591    /// and/or as a read-only image in a shader (which can be read as a sampled image,
592    /// combined image/sampler and/or input attachment).
593    DepthStencilReadOnlyOpt = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL as _,
594    /// must only be used as a read-only image in a shader (which can be read as a sampled image,
595    /// combined image/sampler and/or input attachment).
596    ShaderReadOnlyOpt = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL as _,
597    /// must only be used as a source image of a transfer command
598    TransferSrcOpt = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL as _,
599    /// must only be used as a destination image of a transfer command
600    TransferDestOpt = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL as _,
601    /// must only be used for presenting a swapchain image for display
602    #[cfg(feature = "VK_KHR_swapchain")]
603    PresentSrc = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR as _,
604}
605impl ImageLayout {
606    /// Commonly used access types with the layout
607    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    /// Constructs the transition between image layouts.
623    #[inline(always)]
624    pub const fn to(self, after: Self) -> LayoutTransition {
625        LayoutTransition { from: self, to: after }
626    }
627    /// Constructs the transition between image layouts (in reverse order).
628    #[inline(always)]
629    pub const fn from(self, before: Self) -> LayoutTransition {
630        LayoutTransition { from: before, to: self }
631    }
632    /// Constructs the transition from undefined layout to this layout (convenient function).
633    #[inline(always)]
634    pub const fn from_undefined(self) -> LayoutTransition {
635        self.from(Self::Undefined)
636    }
637
638    /// Constructs the empty transition.
639    #[inline(always)]
640    pub const fn keep(self) -> LayoutTransition {
641        LayoutTransition { from: self, to: self }
642    }
643}
644
645/// Represents the transition between image layouts.
646#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
647pub struct LayoutTransition {
648    pub from: ImageLayout,
649    pub to: ImageLayout,
650}
651
652/// Bitmask specifying intended usage of an image.
653#[derive(Clone, Copy, PartialEq, Eq, Hash)]
654#[bitflags_newtype]
655pub struct ImageUsageFlags(VkImageUsageFlags);
656impl ImageUsageFlags {
657    /// The image can be used as the source of a transfer command
658    pub const TRANSFER_SRC: Self = Self(VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
659    /// The image can be used as the destination of a transfer command
660    pub const TRANSFER_DEST: Self = Self(VK_IMAGE_USAGE_TRANSFER_DST_BIT);
661    /// The image can be used to create `ImageView` suitable for occupying a `DescriptorSet` slot
662    /// either of type `DescriptorType::SampledImage` or `DescriptorType::CombinedImageSampler`, and be sampled by a shader
663    pub const SAMPLED: Self = Self(VK_IMAGE_USAGE_SAMPLED_BIT);
664    /// The image can be used to create a `ImageView` suitable for occupying a `DescriptorSet` slot of type `DescriptorType::StorageImage`
665    pub const STORAGE: Self = Self(VK_IMAGE_USAGE_STORAGE_BIT);
666    /// The image can be used to create a `ImageView` suitable for use as a color or resolve attachment in a `Framebuffer`
667    pub const COLOR_ATTACHMENT: Self = Self(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
668    /// The image can be used to create a `ImageView` suitable for use as a depth/stencil attachment in a `Framebuffer`
669    pub const DEPTH_STENCIL_ATTACHMENT: Self = Self(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
670    /// The memory bound to this image will have been allocated with the `VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT`
671    /// This bit can be set for any image that can be used to create a `ImageView` suitable for use as a color, resolve, depth/stencil,
672    /// or input attachment
673    pub const TRANSIENT_ATTACHMENT: Self = Self(VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT);
674    /// The image can be used to create a `ImageView` suitable for occupying `DescriptorSet` slot of type `DescriptorType::InputAttachment`;
675    /// be read from a shader as an input attachment; and be used as an input attachment in a framebuffer
676    pub const INPUT_ATTACHMENT: Self = Self(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
677}
678
679/// Bitmask specifying additional parameters of an image
680#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
681#[bitflags_newtype]
682pub struct ImageFlags(VkImageCreateFlags);
683impl ImageFlags {
684    /// Empty bits
685    pub const EMPTY: Self = Self(0);
686    /// The image will be backed using sparse memory binding
687    pub const SPARSE_BINDING: Self = Self(VK_IMAGE_CREATE_SPARSE_BINDING_BIT);
688    /// The image can be partially backed using sparse memory binding. This bit is with `SPARSE_BINDING` implicitly
689    pub const SPARSE_RESIDENCY: Self = Self(VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
690    /// The image will be backed using sparse memory binding with memory ranges
691    /// that might also simultaneously be backing another image. This bit is with `SPARSE_BINDING` implicitly
692    pub const SPARSE_ALIASED: Self = Self(VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT);
693    /// The image can be used to create a `ImageView` with a different format from the image
694    pub const MUTABLE_FORMAT: Self = Self(VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT);
695    /// The image can be used to create a `ImageView` of type `ImageViewType::Cube` or `ImageViewType::CubeArray`
696    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/// Bitmask specifying which aspects of an image are included in a view
736#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
737#[bitflags_newtype]
738pub struct AspectMask(VkImageAspectFlags);
739impl AspectMask {
740    /// No aspect mask
741    pub const EMPTY: Self = Self(0);
742    /// The color aspect
743    pub const COLOR: Self = Self(VK_IMAGE_ASPECT_COLOR_BIT);
744    /// The depth aspect
745    pub const DEPTH: Self = Self(VK_IMAGE_ASPECT_DEPTH_BIT);
746    /// The stencil aspect
747    pub const STENCIL: Self = Self(VK_IMAGE_ASPECT_STENCIL_BIT);
748    /// The metadata aspect, used for sparse sparse resource operations
749    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    /// Constructs a new [`ImageSubresourceRange`] data
778    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    /// Retrieves single subresource slice in this range
793    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/// Opaque handle to a image view object
803#[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    /// Constructs from raw values
848    /// # Safety
849    /// the resource must be created from the parent
850    pub const unsafe fn manage(handle: VkImageView, parent: Image) -> Self {
851        Self(handle, parent)
852    }
853
854    /// Purges internal values (Drop will not be called for this resource)
855    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    /// Owning parent object by cloning it.
865    #[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    /// Create a new image view from an existing image
875    /// # Failure
876    /// On failure, this command returns
877    ///
878    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
879    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
880    /// * [`VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR`]
881    #[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    /// Create a new image view from an existing image
988    /// # Failure
989    /// On failure, this command returns
990    ///
991    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
992    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
993    /// * `VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR`
994    #[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}