Skip to main content

bedrock/resources/
image.rs

1use bedrock_vk::{self as brvk, TypedVulkanStructure, VkRawHandle};
2
3use crate::ffi_helper::slice_as_ptr_empty_null;
4use crate::*;
5use derives::{bitflags_newtype, implements};
6
7pub trait Image: VkHandle<Handle = brvk::VkImage> + DeviceChildHandle {
8    /// The pixel format of an image
9    fn format(&self) -> brvk::VkFormat;
10
11    /// The size of an image
12    fn size(&self) -> &brvk::VkExtent3D;
13
14    fn dimension(&self) -> brvk::VkImageViewType;
15
16    /// Query a count of the memory requirements for a sparse image
17    #[implements]
18    #[inline]
19    fn sparse_requirement_count(&self) -> u32 {
20        let mut n = 0;
21        unsafe {
22            brvk::fns::get_image_sparse_memory_requirements(
23                self.device_handle(),
24                self.native_ptr(),
25                &mut n,
26                core::ptr::null_mut(),
27            );
28        }
29
30        n
31    }
32
33    /// Query the memory requirements for a sparse image
34    #[implements]
35    #[inline]
36    fn sparse_requirements(&self, sink: &mut [core::mem::MaybeUninit<brvk::VkSparseImageMemoryRequirements>]) -> u32 {
37        let mut n = sink.len() as _;
38        unsafe {
39            brvk::fns::get_image_sparse_memory_requirements(
40                self.device_handle(),
41                self.native_ptr(),
42                &mut n,
43                sink.as_mut_ptr() as _,
44            );
45        }
46
47        n
48    }
49
50    /// Query the memory requirements for a sparse image
51    #[implements("alloc")]
52    fn sparse_requirements_alloc(&self) -> Vec<brvk::VkSparseImageMemoryRequirements> {
53        let n = self.sparse_requirement_count() as usize;
54        if n == 0 {
55            // no items
56            return crate::alloc::empty_sink_buffer();
57        }
58
59        let mut xs = Vec::with_capacity(n);
60        let n = self.sparse_requirements(xs.spare_capacity_mut()) as usize;
61        unsafe {
62            xs.set_len(n);
63        }
64
65        xs
66    }
67
68    /// Retrieve information about an image subresource
69    #[implements]
70    fn layout_info(&self, subresource: &ImageSubresource) -> brvk::VkSubresourceLayout {
71        let mut s = core::mem::MaybeUninit::uninit();
72        unsafe {
73            brvk::fns::get_image_subresource_layout(
74                self.device_handle(),
75                self.native_ptr(),
76                &subresource.0,
77                s.as_mut_ptr(),
78            );
79
80            s.assume_init()
81        }
82    }
83
84    #[inline]
85    fn memory_barrier(&self, subresource_range: ImageSubresourceRange, trans: LayoutTransition) -> ImageMemoryBarrier {
86        ImageMemoryBarrier::new(self, subresource_range.0, trans)
87    }
88
89    #[cfg(feature = "VK_KHR_synchronization2")]
90    #[inline]
91    fn memory_barrier2<'r>(&'r self, subresource_range: ImageSubresourceRange) -> crate::ImageMemoryBarrier2<'r> {
92        crate::ImageMemoryBarrier2::new(self, subresource_range)
93    }
94
95    /// Returns an image's DRM format modifier
96    #[implements("VK_EXT_image_drm_format_modifier")]
97    #[inline]
98    unsafe fn drm_format_modifier_properties_raw(
99        &self,
100        sink: &mut core::mem::MaybeUninit<brvk::VkImageDrmFormatModifierPropertiesEXT>,
101    ) -> crate::Result<()>
102    where
103        Self: DeviceChild<ConcreteDevice: DeviceImageDrmFormatModifierExtension>,
104    {
105        use crate::Device;
106
107        crate::error::translate_vk_result(self.device().get_image_drm_format_modifier_properties_ext_fn().0(
108            self.device_handle(),
109            self.native_ptr(),
110            sink.as_mut_ptr(),
111        ))?;
112
113        Ok(())
114    }
115
116    /// Returns an image's DRM format modifier
117    #[implements("VK_EXT_image_drm_format_modifier")]
118    fn drm_format_modifier_properties(&self) -> crate::Result<brvk::VkImageDrmFormatModifierPropertiesEXT>
119    where
120        Self: DeviceChild<ConcreteDevice: DeviceImageDrmFormatModifierExtension>,
121    {
122        let mut properties = core::mem::MaybeUninit::<brvk::VkImageDrmFormatModifierPropertiesEXT>::uninit();
123        unsafe {
124            let p = properties.as_mut_ptr();
125            core::ptr::addr_of_mut!((*p).sType)
126                .write(<brvk::VkImageDrmFormatModifierPropertiesEXT as brvk::TypedVulkanSinkStructure>::TYPE);
127            core::ptr::addr_of_mut!((*p).pNext).write(core::ptr::null_mut());
128
129            self.drm_format_modifier_properties_raw(&mut properties)?;
130
131            Ok(properties.assume_init())
132        }
133    }
134}
135DerefContainerBracketImpl!(for Image {
136    #[inline(always)]
137    fn format(&self) -> brvk::VkFormat {
138        T::format(self)
139    }
140
141    #[inline(always)]
142    fn size(&self) -> &brvk::VkExtent3D {
143        T::size(self)
144    }
145
146    #[inline(always)]
147    fn dimension(&self) -> brvk::VkImageViewType {
148        T::dimension(self)
149    }
150});
151GuardsImpl!(for Image {
152    #[inline(always)]
153    fn format(&self) -> brvk::VkFormat {
154        T::format(self)
155    }
156
157    #[inline(always)]
158    fn size(&self) -> &brvk::VkExtent3D {
159        T::size(self)
160    }
161
162    #[inline(always)]
163    fn dimension(&self) -> brvk::VkImageViewType {
164        T::dimension(self)
165    }
166});
167
168pub trait DeviceChildImage: Image + DeviceChild {}
169impl<T: Image + DeviceChild> DeviceChildImage for T {}
170
171pub trait ImageChild {
172    type ConcreteImage: crate::Image;
173
174    fn image(&self) -> &Self::ConcreteImage;
175}
176DerefContainerBracketImpl!(for ImageChild {
177    type ConcreteImage = T::ConcreteImage;
178
179    #[inline(always)]
180    fn image(&self) -> &Self::ConcreteImage { T::image(self) }
181});
182GuardsImpl!(for ImageChild {
183    type ConcreteImage = T::ConcreteImage;
184
185    #[inline(always)]
186    fn image(&self) -> &Self::ConcreteImage { T::image(self) }
187});
188
189pub trait ImageChildMut: ImageChild {
190    fn image_mut(&mut self) -> &mut Self::ConcreteImage;
191}
192DerefContainerBracketImpl!(for mut ImageChildMut {
193    #[inline(always)]
194    fn image_mut(&mut self) -> &mut Self::ConcreteImage {
195        T::image_mut(self)
196    }
197});
198GuardsImpl!(for mut ImageChildMut {
199    #[inline(always)]
200    fn image_mut(&mut self) -> &mut Self::ConcreteImage {
201        T::image_mut(self)
202    }
203});
204
205pub trait ImageView: VkHandle<Handle = brvk::VkImageView> {}
206DerefContainerBracketImpl!(for ImageView {});
207GuardsImpl!(for ImageView {});
208
209pub trait ConcreteDeviceImageView: ImageView + DeviceChild {}
210DerefContainerBracketImpl!(for ConcreteDeviceImageView {});
211GuardsImpl!(for ConcreteDeviceImageView {});
212
213/// Image Dimension by corresponding extent type
214pub trait ImageSize {
215    const DIMENSION: brvk::VkImageType;
216
217    fn conv(self) -> brvk::VkExtent3D;
218}
219impl ImageSize for u32 {
220    const DIMENSION: brvk::VkImageType = brvk::VK_IMAGE_TYPE_1D;
221
222    #[inline(always)]
223    fn conv(self) -> brvk::VkExtent3D {
224        brvk::VkExtent3D {
225            width: self,
226            height: 1,
227            depth: 1,
228        }
229    }
230}
231impl ImageSize for brvk::VkExtent2D {
232    const DIMENSION: brvk::VkImageType = brvk::VK_IMAGE_TYPE_2D;
233
234    #[inline(always)]
235    fn conv(self) -> brvk::VkExtent3D {
236        brvk::VkExtent3D {
237            width: self.width,
238            height: self.height,
239            depth: 1,
240        }
241    }
242}
243impl ImageSize for brvk::VkExtent3D {
244    const DIMENSION: brvk::VkImageType = brvk::VK_IMAGE_TYPE_3D;
245
246    #[inline(always)]
247    fn conv(self) -> brvk::VkExtent3D {
248        self
249    }
250}
251
252/// Opaque handle to a image object(constructed via `ImageDesc`)
253#[derive(VkHandle, VkObject)]
254#[VkObject(type = brvk::VkImage::OBJECT_TYPE)]
255pub struct ImageObject<Device: VkHandle<Handle = brvk::VkDevice>>(
256    brvk::VkImage,
257    Device,
258    brvk::VkImageType,
259    brvk::VkFormat,
260    brvk::VkExtent3D,
261);
262#[implements]
263impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for ImageObject<Device> {
264    #[inline(always)]
265    fn drop(&mut self) {
266        unsafe {
267            crate::vkfn_wrapper::destroy_image(self.device_transparent_ref(), VkHandleRefMut::dangling(self.0), None);
268        }
269    }
270}
271unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for ImageObject<Device> {}
272unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for ImageObject<Device> {}
273impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for ImageObject<Device> {
274    #[inline(always)]
275    fn device_handle(&self) -> brvk::VkDevice {
276        self.1.native_ptr()
277    }
278}
279impl<Device: crate::Device> DeviceChild for ImageObject<Device> {
280    type ConcreteDevice = Device;
281
282    #[inline(always)]
283    fn device(&self) -> &Self::ConcreteDevice {
284        &self.1
285    }
286}
287impl<Device: VkHandle<Handle = brvk::VkDevice>> Image for ImageObject<Device> {
288    fn format(&self) -> brvk::VkFormat {
289        self.3
290    }
291
292    fn size(&self) -> &brvk::VkExtent3D {
293        &self.4
294    }
295
296    fn dimension(&self) -> brvk::VkImageViewType {
297        match self.2 {
298            brvk::VK_IMAGE_TYPE_1D => brvk::VK_IMAGE_VIEW_TYPE_1D,
299            brvk::VK_IMAGE_TYPE_2D => brvk::VK_IMAGE_VIEW_TYPE_2D,
300            brvk::VK_IMAGE_TYPE_3D => brvk::VK_IMAGE_VIEW_TYPE_3D,
301            _ => unreachable!(),
302        }
303    }
304}
305impl<Device: VkHandle<Handle = brvk::VkDevice>> MemoryBound for ImageObject<Device> {
306    #[cfg(feature = "VK_KHR_get_memory_requirements2")]
307    type MemoryRequirementsInfo2<'b>
308        = ImageMemoryRequirementsInfo2<'b, Self>
309    where
310        Device: 'b;
311
312    #[implements]
313    #[inline(always)]
314    fn requirements(&self) -> brvk::VkMemoryRequirements {
315        unsafe {
316            crate::vkfn_wrapper::get_image_memory_requirements(self.device_transparent_ref(), self.as_transparent_ref())
317        }
318    }
319
320    #[cfg(feature = "VK_KHR_get_memory_requirements2")]
321    fn requirements2<'b>(&'b self) -> Self::MemoryRequirementsInfo2<'b> {
322        ImageMemoryRequirementsInfo2::new(self)
323    }
324
325    #[implements]
326    #[inline(always)]
327    fn bind(
328        &mut self,
329        memory: &(impl VkHandle<Handle = brvk::VkDeviceMemory> + ?Sized),
330        offset: DeviceSize,
331    ) -> crate::Result<()>
332    where
333        Self: VkHandleMut,
334    {
335        unsafe {
336            crate::vkfn_wrapper::bind_image_memory(
337                self.device_transparent_ref(),
338                VkHandleRefMut::dangling(self.0),
339                memory.as_transparent_ref(),
340                offset as _,
341            )
342        }
343    }
344}
345impl<Device: VkHandle<Handle = brvk::VkDevice>> ImageObject<Device> {
346    /// Constructs from raw values
347    /// # Safety
348    /// the resource must be created from the parent
349    pub const unsafe fn manage(
350        handle: brvk::VkImage,
351        parent: Device,
352        image_type: brvk::VkImageType,
353        format: brvk::VkFormat,
354        extent: brvk::VkExtent3D,
355    ) -> Self {
356        Self(handle, parent, image_type, format, extent)
357    }
358
359    /// Purges internal values (Drop will not be called for this resource)
360    pub const fn unmanage(
361        self,
362    ) -> (
363        brvk::VkImage,
364        Device,
365        brvk::VkImageType,
366        brvk::VkFormat,
367        brvk::VkExtent3D,
368    ) {
369        let v = self.0;
370        let p = unsafe { core::ptr::read(&self.1) };
371        let (t, f, x) = (self.2, self.3, self.4);
372        core::mem::forget(self);
373
374        (v, p, t, f, x)
375    }
376}
377impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> ImageObject<&'_ Device> {
378    /// Owning parent object by cloning it.
379    #[inline(always)]
380    pub fn clone_parent(self) -> ImageObject<Device> {
381        let r = ImageObject(self.0, self.1.clone(), self.2, self.3, self.4);
382        core::mem::forget(self);
383
384        r
385    }
386}
387impl<Device: crate::Device> ImageObject<Device> {
388    /// Create a new image object
389    /// # Failure
390    /// On failure, this command returns
391    ///
392    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
393    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
394    /// * [`brvk::VK_ERROR_COMPRESSION_EXHAUSTED_EXT`]
395    /// * [`brvk::VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR`]
396    #[implements]
397    #[inline]
398    pub fn new(device: Device, info: &ImageCreateInfo) -> crate::Result<Self> {
399        Ok(unsafe {
400            Self::manage(
401                device.new_image_raw(info, None)?,
402                device,
403                info.0.imageType,
404                info.0.format,
405                info.0.extent,
406            )
407        })
408    }
409}
410
411#[repr(transparent)]
412#[derive(Clone)]
413pub struct ImageCreateInfo<'d>(
414    brvk::VkImageCreateInfo,
415    #[allow(clippy::type_complexity)]
416    core::marker::PhantomData<(Option<&'d dyn brvk::VulkanStructure>, Option<&'d [u32]>)>,
417);
418impl<'d> ImageCreateInfo<'d> {
419    #[inline(always)]
420    pub fn new<Size: ImageSize>(size: Size, format: brvk::VkFormat) -> Self {
421        Self(
422            brvk::VkImageCreateInfo {
423                sType: brvk::VkImageCreateInfo::TYPE,
424                pNext: core::ptr::null(),
425                flags: 0,
426                imageType: Size::DIMENSION,
427                extent: size.conv(),
428                format,
429                usage: 0,
430                mipLevels: 1,
431                arrayLayers: 1,
432                samples: 1,
433                initialLayout: brvk::VK_IMAGE_LAYOUT_UNDEFINED,
434                tiling: brvk::VK_IMAGE_TILING_OPTIMAL,
435                sharingMode: brvk::VK_SHARING_MODE_EXCLUSIVE,
436                queueFamilyIndexCount: 0,
437                pQueueFamilyIndices: core::ptr::null(),
438            },
439            core::marker::PhantomData,
440        )
441    }
442
443    /// # Safety
444    ///
445    /// `raw` must be a valid [`brvk::VkImageCreateInfo`] struct.
446    pub const unsafe fn from_raw(raw: brvk::VkImageCreateInfo) -> Self {
447        Self(raw, core::marker::PhantomData)
448    }
449
450    pub const fn into_raw(self) -> brvk::VkImageCreateInfo {
451        self.0
452    }
453
454    #[inline(always)]
455    pub fn with_next(mut self, next: &'d (impl brvk::TypedVulkanStructure + ?Sized)) -> Self {
456        self.0.pNext = next.as_generic() as *const _ as _;
457        self
458    }
459
460    /// Sets an size and a dimension of the created image.
461    #[inline(always)]
462    pub fn size<Size: ImageSize>(mut self, size: Size) -> Self {
463        self.0.extent = size.conv();
464        self.0.imageType = Size::DIMENSION;
465
466        self
467    }
468
469    /// Sets an initial layout for the created image.
470    /// default: Undefined layout
471    pub const fn init_layout(mut self, layout: ImageLayout) -> Self {
472        self.0.initialLayout = layout as _;
473        self
474    }
475
476    /// A list of queue families that will access this image,
477    /// or an empty list if no queue families can access this image simultaneously
478    pub const fn sharing_queue_families(mut self, indices: &'d [u32]) -> Self {
479        self.0.sharingMode = if indices.is_empty() {
480            brvk::VK_SHARING_MODE_EXCLUSIVE
481        } else {
482            brvk::VK_SHARING_MODE_CONCURRENT
483        };
484        self.0.queueFamilyIndexCount = indices.len() as _;
485        self.0.pQueueFamilyIndices = slice_as_ptr_empty_null(indices);
486
487        self
488    }
489
490    /// The number of sub-data element samples in the image
491    /// bitmask of 1(default), 2, 4, 8, 16, 32, 64
492    pub const fn sample_counts(mut self, count_bits: u32) -> Self {
493        self.0.samples = count_bits;
494        self
495    }
496
497    /// Sets the tiling arrangement of the data elements in memory as "linear tiling"
498    /// default: optimal tiling
499    pub const fn use_linear_tiling(mut self) -> Self {
500        self.0.tiling = brvk::VK_IMAGE_TILING_LINEAR;
501        self
502    }
503
504    /// A bitmask of `ImageFlags`describing additional parameters of the image
505    /// default: none
506    pub const fn flags(mut self, opt: ImageFlags) -> Self {
507        self.0.flags = opt.0;
508        self
509    }
510
511    /// The number of layers in the image
512    /// default: 1
513    pub const fn array_layers(mut self, layers: u32) -> Self {
514        self.0.arrayLayers = layers;
515        self
516    }
517
518    /// The number of levels of detail available for minified sampling of the image
519    /// default: 1
520    pub const fn mip_levels(mut self, levels: u32) -> Self {
521        self.0.mipLevels = levels;
522        self
523    }
524
525    /// Merges some custom usage flag bits.
526    pub const fn with_usage(mut self, bits: ImageUsageFlags) -> Self {
527        self.0.usage |= bits.0;
528        self
529    }
530
531    /// Overwrites all of custom usage flag bits.
532    pub const fn set_usage(mut self, bits: ImageUsageFlags) -> Self {
533        self.0.usage = bits.0;
534        self
535    }
536}
537impl AsRef<brvk::VkImageCreateInfo> for ImageCreateInfo<'_> {
538    #[inline(always)]
539    fn as_ref(&self) -> &brvk::VkImageCreateInfo {
540        &self.0
541    }
542}
543
544#[cfg(feature = "VK_KHR_get_memory_requirements2")]
545pub struct ImageMemoryRequirementsInfo2<'b, Image: VkHandle<Handle = brvk::VkImage> + 'b>(
546    brvk::VkImageMemoryRequirementsInfo2KHR,
547    &'b Image,
548);
549#[cfg(feature = "VK_KHR_get_memory_requirements2")]
550impl<'b, Image: VkHandle<Handle = brvk::VkImage> + 'b> ImageMemoryRequirementsInfo2<'b, Image> {
551    pub fn new(image: &'b Image) -> Self {
552        Self(
553            brvk::VkImageMemoryRequirementsInfo2KHR {
554                sType: brvk::VkImageMemoryRequirementsInfo2KHR::TYPE,
555                pNext: core::ptr::null(),
556                image: image.native_ptr(),
557            },
558            image,
559        )
560    }
561
562    #[implements("Allow1_1APIs")]
563    #[inline(always)]
564    pub fn query(self, sink: &mut core::mem::MaybeUninit<brvk::VkMemoryRequirements2KHR>)
565    where
566        Image: crate::DeviceChild,
567    {
568        unsafe {
569            crate::vkfn_wrapper::get_image_memory_requirements2(self.1.device_transparent_ref(), &self, sink);
570        }
571    }
572}
573#[cfg(feature = "VK_KHR_get_memory_requirements2")]
574impl<Image: VkHandle<Handle = brvk::VkImage>> AsRef<brvk::VkImageMemoryRequirementsInfo2KHR>
575    for ImageMemoryRequirementsInfo2<'_, Image>
576{
577    fn as_ref(&self) -> &brvk::VkImageMemoryRequirementsInfo2KHR {
578        &self.0
579    }
580}
581
582#[cfg(feature = "VK_KHR_bind_memory2")]
583#[repr(transparent)]
584pub struct BindImageMemoryInfo<'b>(
585    brvk::VkBindImageMemoryInfoKHR,
586    core::marker::PhantomData<(VkHandleRef<'b, brvk::VkImage>, VkHandleRef<'b, brvk::VkDeviceMemory>)>,
587);
588#[cfg(feature = "VK_KHR_bind_memory2")]
589impl<'b> BindImageMemoryInfo<'b> {
590    pub fn new(
591        image: &'b (impl VkHandle<Handle = brvk::VkImage> + ?Sized),
592        memory: &'b (impl VkHandle<Handle = brvk::VkDeviceMemory> + ?Sized),
593        offset: brvk::VkDeviceSize,
594    ) -> Self {
595        Self(
596            brvk::VkBindImageMemoryInfoKHR {
597                sType: brvk::VkBindImageMemoryInfoKHR::TYPE,
598                pNext: core::ptr::null(),
599                image: image.native_ptr(),
600                memory: memory.native_ptr(),
601                memoryOffset: offset,
602            },
603            core::marker::PhantomData,
604        )
605    }
606
607    /// # Safety
608    ///
609    /// `raw` must be a valid [`VkBindImageMemoryInfoKHR`] struct.
610    pub const unsafe fn from_raw(raw: brvk::VkBindImageMemoryInfoKHR) -> Self {
611        Self(raw, core::marker::PhantomData)
612    }
613
614    pub const fn into_raw(self) -> brvk::VkBindImageMemoryInfoKHR {
615        self.0
616    }
617}
618#[cfg(feature = "VK_KHR_bind_memory2")]
619impl AsRef<brvk::VkBindImageMemoryInfoKHR> for BindImageMemoryInfo<'_> {
620    #[inline(always)]
621    fn as_ref(&self) -> &brvk::VkBindImageMemoryInfoKHR {
622        &self.0
623    }
624}
625
626/// Layouts of image and image subresources
627#[repr(u32)]
628#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
629pub enum ImageLayout {
630    /// does not support device access
631    Undefined = brvk::VK_IMAGE_LAYOUT_UNDEFINED as _,
632    /// does not support device access. host can be written to this memory immediately
633    Preinitialized = brvk::VK_IMAGE_LAYOUT_PREINITIALIZED as _,
634    /// supports all types of device access
635    General = brvk::VK_IMAGE_LAYOUT_GENERAL as _,
636    /// must only be used as a color or resolve attachment in a `Framebuffer`
637    ColorAttachmentOpt = brvk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL as _,
638    /// must only be used as a depth/stencil attachment in a `Framebuffer`
639    DepthStencilAttachmentOpt = brvk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL as _,
640    /// must only be used as a read-only depth/stencil attachment in a `Framebuffer`
641    /// and/or as a read-only image in a shader (which can be read as a sampled image,
642    /// combined image/sampler and/or input attachment).
643    DepthStencilReadOnlyOpt = brvk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL as _,
644    /// must only be used as a read-only image in a shader (which can be read as a sampled image,
645    /// combined image/sampler and/or input attachment).
646    ShaderReadOnlyOpt = brvk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL as _,
647    /// must only be used as a source image of a transfer command
648    TransferSrcOpt = brvk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL as _,
649    /// must only be used as a destination image of a transfer command
650    TransferDestOpt = brvk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL as _,
651    /// must only be used for presenting a swapchain image for display
652    #[cfg(feature = "VK_KHR_swapchain")]
653    PresentSrc = brvk::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR as _,
654}
655impl ImageLayout {
656    /// Commonly used access types with the layout
657    pub fn default_access_mask(self) -> brvk::VkAccessFlags {
658        match self {
659            Self::Undefined | Self::Preinitialized => 0,
660            Self::General => brvk::VK_ACCESS_MEMORY_READ_BIT,
661            Self::ColorAttachmentOpt => brvk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
662            Self::DepthStencilAttachmentOpt => brvk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
663            Self::DepthStencilReadOnlyOpt => brvk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
664            Self::ShaderReadOnlyOpt => brvk::VK_ACCESS_SHADER_READ_BIT,
665            Self::TransferSrcOpt => brvk::VK_ACCESS_TRANSFER_READ_BIT,
666            Self::TransferDestOpt => brvk::VK_ACCESS_TRANSFER_WRITE_BIT,
667            #[cfg(feature = "VK_KHR_swapchain")]
668            Self::PresentSrc => brvk::VK_ACCESS_MEMORY_READ_BIT,
669        }
670    }
671
672    /// Constructs the transition between image layouts.
673    #[inline(always)]
674    pub const fn to(self, after: Self) -> LayoutTransition {
675        LayoutTransition { from: self, to: after }
676    }
677    /// Constructs the transition between image layouts (in reverse order).
678    #[inline(always)]
679    pub const fn from(self, before: Self) -> LayoutTransition {
680        LayoutTransition { from: before, to: self }
681    }
682    /// Constructs the transition from undefined layout to this layout (convenient function).
683    #[inline(always)]
684    pub const fn from_undefined(self) -> LayoutTransition {
685        self.from(Self::Undefined)
686    }
687
688    /// Constructs the empty transition.
689    #[inline(always)]
690    pub const fn keep(self) -> LayoutTransition {
691        LayoutTransition { from: self, to: self }
692    }
693}
694
695/// Represents the transition between image layouts.
696#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
697pub struct LayoutTransition {
698    pub from: ImageLayout,
699    pub to: ImageLayout,
700}
701
702/// Bitmask specifying intended usage of an image.
703#[derive(Clone, Copy, PartialEq, Eq, Hash)]
704#[bitflags_newtype]
705pub struct ImageUsageFlags(brvk::VkImageUsageFlags);
706impl ImageUsageFlags {
707    /// The image can be used as the source of a transfer command
708    pub const TRANSFER_SRC: Self = Self(brvk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
709    /// The image can be used as the destination of a transfer command
710    pub const TRANSFER_DEST: Self = Self(brvk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
711    /// The image can be used to create `ImageView` suitable for occupying a `DescriptorSet` slot
712    /// either of type `DescriptorType::SampledImage` or `DescriptorType::CombinedImageSampler`, and be sampled by a shader
713    pub const SAMPLED: Self = Self(brvk::VK_IMAGE_USAGE_SAMPLED_BIT);
714    /// The image can be used to create a `ImageView` suitable for occupying a `DescriptorSet` slot of type `DescriptorType::StorageImage`
715    pub const STORAGE: Self = Self(brvk::VK_IMAGE_USAGE_STORAGE_BIT);
716    /// The image can be used to create a `ImageView` suitable for use as a color or resolve attachment in a `Framebuffer`
717    pub const COLOR_ATTACHMENT: Self = Self(brvk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
718    /// The image can be used to create a `ImageView` suitable for use as a depth/stencil attachment in a `Framebuffer`
719    pub const DEPTH_STENCIL_ATTACHMENT: Self = Self(brvk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
720    /// The memory bound to this image will have been allocated with the `brvk::VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT`
721    /// 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,
722    /// or input attachment
723    pub const TRANSIENT_ATTACHMENT: Self = Self(brvk::VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT);
724    /// The image can be used to create a `ImageView` suitable for occupying `DescriptorSet` slot of type `DescriptorType::InputAttachment`;
725    /// be read from a shader as an input attachment; and be used as an input attachment in a framebuffer
726    pub const INPUT_ATTACHMENT: Self = Self(brvk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
727}
728
729/// Bitmask specifying additional parameters of an image
730#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
731#[bitflags_newtype]
732pub struct ImageFlags(brvk::VkImageCreateFlags);
733impl ImageFlags {
734    /// Empty bits
735    pub const EMPTY: Self = Self(0);
736    /// The image will be backed using sparse memory binding
737    pub const SPARSE_BINDING: Self = Self(brvk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT);
738    /// The image can be partially backed using sparse memory binding. This bit is with `SPARSE_BINDING` implicitly
739    pub const SPARSE_RESIDENCY: Self =
740        Self(brvk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | brvk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
741    /// The image will be backed using sparse memory binding with memory ranges
742    /// that might also simultaneously be backing another image. This bit is with `SPARSE_BINDING` implicitly
743    pub const SPARSE_ALIASED: Self =
744        Self(brvk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | brvk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT);
745    /// The image can be used to create a `ImageView` with a different format from the image
746    pub const MUTABLE_FORMAT: Self = Self(brvk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT);
747    /// The image can be used to create a `ImageView` of type `ImageViewType::Cube` or `ImageViewType::CubeArray`
748    pub const CUBE_COMPATIBLE: Self = Self(brvk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT);
749}
750
751#[cfg(feature = "VK_KHR_get_memory_requirements2")]
752#[repr(transparent)]
753#[derive(Clone)]
754pub struct ImageSparseMemoryRequirementsInfo2<'r>(
755    pub(crate) brvk::VkImageSparseMemoryRequirementsInfo2KHR,
756    core::marker::PhantomData<(
757        Option<&'r dyn brvk::VulkanStructure>,
758        &'r dyn VkHandle<Handle = brvk::VkImage>,
759    )>,
760);
761#[cfg(feature = "VK_KHR_get_memory_requirements2")]
762impl<'r> ImageSparseMemoryRequirementsInfo2<'r> {
763    #[inline]
764    pub fn new(image: &'r (impl VkHandle<Handle = brvk::VkImage> + ?Sized)) -> Self {
765        Self(
766            brvk::VkImageSparseMemoryRequirementsInfo2KHR {
767                sType: brvk::VkImageSparseMemoryRequirementsInfo2KHR::TYPE,
768                pNext: core::ptr::null(),
769                image: image.native_ptr(),
770            },
771            core::marker::PhantomData,
772        )
773    }
774
775    /// # Safety
776    ///
777    /// `raw` must be a valid [`brvk::VkImageSparseMemoryRequirementsInfo2KHR`] struct.
778    pub const unsafe fn from_raw(raw: brvk::VkImageSparseMemoryRequirementsInfo2KHR) -> Self {
779        Self(raw, core::marker::PhantomData)
780    }
781
782    pub const fn into_raw(self) -> brvk::VkImageSparseMemoryRequirementsInfo2KHR {
783        self.0
784    }
785
786    #[inline]
787    pub fn with_next(mut self, next: &'r (impl brvk::VulkanStructure + ?Sized)) -> Self {
788        self.0.pNext = next.as_generic() as *const _ as _;
789        self
790    }
791}
792
793/// Bitmask specifying which aspects of an image are included in a view
794#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
795#[bitflags_newtype]
796pub struct AspectMask(brvk::VkImageAspectFlags);
797impl AspectMask {
798    /// No aspect mask
799    pub const EMPTY: Self = Self(0);
800    /// The color aspect
801    pub const COLOR: Self = Self(brvk::VK_IMAGE_ASPECT_COLOR_BIT);
802    /// The depth aspect
803    pub const DEPTH: Self = Self(brvk::VK_IMAGE_ASPECT_DEPTH_BIT);
804    /// The stencil aspect
805    pub const STENCIL: Self = Self(brvk::VK_IMAGE_ASPECT_STENCIL_BIT);
806    /// The metadata aspect, used for sparse sparse resource operations
807    pub const METADATA: Self = Self(brvk::VK_IMAGE_ASPECT_METADATA_BIT);
808}
809
810#[repr(transparent)]
811#[derive(Debug, Clone)]
812pub struct ImageSubresource(pub brvk::VkImageSubresource);
813impl ImageSubresource {
814    pub const fn new(aspect_mask: AspectMask, mip_level: u32, array_layer: u32) -> Self {
815        Self(brvk::VkImageSubresource {
816            aspectMask: aspect_mask.bits(),
817            mipLevel: mip_level,
818            arrayLayer: array_layer,
819        })
820    }
821}
822
823#[repr(transparent)]
824#[derive(Debug, Clone)]
825pub struct ImageSubresourceLayers(pub brvk::VkImageSubresourceLayers);
826impl ImageSubresourceLayers {
827    pub const fn new(aspect_mask: AspectMask, mip_level: u32, layer_range: core::ops::Range<u32>) -> Self {
828        Self(brvk::VkImageSubresourceLayers {
829            aspectMask: aspect_mask.bits(),
830            mipLevel: mip_level,
831            baseArrayLayer: layer_range.start,
832            layerCount: layer_range.end - layer_range.start,
833        })
834    }
835}
836
837#[repr(transparent)]
838#[derive(Debug, Clone)]
839pub struct ImageSubresourceRange(pub brvk::VkImageSubresourceRange);
840impl ImageSubresourceRange {
841    /// Constructs a new [`ImageSubresourceRange`] data
842    pub const fn new(
843        aspect_mask: AspectMask,
844        mip_range: core::ops::Range<u32>,
845        array_layer_range: core::ops::Range<u32>,
846    ) -> Self {
847        Self(brvk::VkImageSubresourceRange {
848            aspectMask: aspect_mask.bits(),
849            baseMipLevel: mip_range.start,
850            levelCount: mip_range.end - mip_range.start,
851            baseArrayLayer: array_layer_range.start,
852            layerCount: array_layer_range.end - array_layer_range.start,
853        })
854    }
855
856    /// Retrieves single subresource slice in this range
857    pub const fn subresource(&self, mip_level_offset: u32, array_layer_offset: u32) -> ImageSubresource {
858        ImageSubresource(brvk::VkImageSubresource {
859            aspectMask: self.0.aspectMask,
860            mipLevel: self.0.baseMipLevel + mip_level_offset,
861            arrayLayer: self.0.baseArrayLayer + array_layer_offset,
862        })
863    }
864}
865
866/// Opaque handle to a image view object
867#[derive(VkHandle, VkObject)]
868#[VkObject(type = brvk::VkImageView::OBJECT_TYPE)]
869pub struct ImageViewObject<Image: DeviceChildHandle>(brvk::VkImageView, Image);
870#[implements]
871impl<Image: DeviceChildHandle> Drop for ImageViewObject<Image> {
872    #[inline(always)]
873    fn drop(&mut self) {
874        unsafe {
875            crate::vkfn_wrapper::destroy_image_view(
876                self.device_transparent_ref(),
877                VkHandleRefMut::dangling(self.0),
878                None,
879            );
880        }
881    }
882}
883unsafe impl<Image: DeviceChildHandle + Sync> Sync for ImageViewObject<Image> {}
884unsafe impl<Image: DeviceChildHandle + Send> Send for ImageViewObject<Image> {}
885impl<Image: DeviceChildHandle> DeviceChildHandle for ImageViewObject<Image> {
886    #[inline(always)]
887    fn device_handle(&self) -> brvk::VkDevice {
888        self.1.device_handle()
889    }
890}
891impl<Image: DeviceChild> DeviceChild for ImageViewObject<Image> {
892    type ConcreteDevice = Image::ConcreteDevice;
893
894    #[inline(always)]
895    fn device(&self) -> &Self::ConcreteDevice {
896        self.1.device()
897    }
898}
899impl<Image: self::Image> ImageChild for ImageViewObject<Image> {
900    type ConcreteImage = Image;
901
902    #[inline(always)]
903    fn image(&self) -> &Image {
904        &self.1
905    }
906}
907impl<Image: self::Image> ImageChildMut for ImageViewObject<Image> {
908    #[inline(always)]
909    fn image_mut(&mut self) -> &mut Image {
910        &mut self.1
911    }
912}
913impl<Image: DeviceChildHandle> ImageView for ImageViewObject<Image> {}
914impl<Image: DeviceChildHandle> ImageViewObject<Image> {
915    /// Constructs from raw values
916    /// # Safety
917    /// the resource must be created from the parent
918    pub const unsafe fn manage(handle: brvk::VkImageView, parent: Image) -> Self {
919        Self(handle, parent)
920    }
921
922    /// Purges internal values (Drop will not be called for this resource)
923    pub const fn unmanage(self) -> (brvk::VkImageView, Image) {
924        let v = self.0;
925        let p = unsafe { core::ptr::read(&self.1) };
926        core::mem::forget(self);
927
928        (v, p)
929    }
930}
931impl<Image: DeviceChildHandle + Clone> ImageViewObject<&'_ Image> {
932    /// Owning parent object by cloning it.
933    #[inline(always)]
934    pub fn clone_parent(self) -> ImageViewObject<Image> {
935        let r = ImageViewObject(self.0, self.1.clone());
936        core::mem::forget(self);
937
938        r
939    }
940}
941impl<Image: DeviceChild> ImageViewObject<Image> {
942    /// Create a new image view from an existing image
943    /// # Failure
944    /// On failure, this command returns
945    ///
946    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
947    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
948    /// * [`brvk::VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR`]
949    #[implements]
950    #[inline]
951    pub fn new(image: Image, info: &ImageViewCreateInfo) -> crate::Result<Self> {
952        use crate::Device;
953
954        Ok(unsafe { Self::manage(image.device().new_image_view_raw(info, None)?, image) })
955    }
956}
957
958#[repr(transparent)]
959#[derive(Clone)]
960pub struct ImageViewCreateInfo<'r>(
961    brvk::VkImageViewCreateInfo,
962    core::marker::PhantomData<&'r dyn VkHandle<Handle = brvk::VkImage>>,
963);
964impl<'r> ImageViewCreateInfo<'r> {
965    pub fn new(
966        source: &'r (impl VkHandle<Handle = brvk::VkImage> + ?Sized),
967        subresource_range: ImageSubresourceRange,
968        view_type: brvk::VkImageViewType,
969        format: brvk::VkFormat,
970    ) -> Self {
971        Self(
972            brvk::VkImageViewCreateInfo {
973                sType: brvk::VkImageViewCreateInfo::TYPE,
974                pNext: core::ptr::null(),
975                flags: 0,
976                image: source.native_ptr(),
977                viewType: view_type,
978                format,
979                components: brvk::VkComponentMapping {
980                    r: brvk::VK_COMPONENT_SWIZZLE_R,
981                    g: brvk::VK_COMPONENT_SWIZZLE_G,
982                    b: brvk::VK_COMPONENT_SWIZZLE_B,
983                    a: brvk::VK_COMPONENT_SWIZZLE_A,
984                },
985                subresourceRange: subresource_range.0,
986            },
987            core::marker::PhantomData,
988        )
989    }
990
991    /// # Safety
992    ///
993    /// `raw` must be a valid [`brvk::VkImageViewCreateInfo`] struct.
994    pub const unsafe fn from_raw(raw: brvk::VkImageViewCreateInfo) -> Self {
995        Self(raw, core::marker::PhantomData)
996    }
997
998    pub const fn into_raw(self) -> brvk::VkImageViewCreateInfo {
999        self.0
1000    }
1001
1002    pub const fn with_format_mutation(mut self, format: brvk::VkFormat) -> Self {
1003        self.0.format = format;
1004        self
1005    }
1006
1007    pub const fn with_mapping(mut self, mapping: brvk::VkComponentMapping) -> Self {
1008        self.0.components = mapping;
1009        self
1010    }
1011
1012    pub const fn with_dimension(mut self, dimension: brvk::VkImageViewType) -> Self {
1013        self.0.viewType = dimension;
1014        self
1015    }
1016}
1017
1018pub struct ImageViewBuilder<I: Image>(ImageViewCreateInfo<'static>, I);
1019impl<I: Image> ImageViewBuilder<I> {
1020    pub fn new(source: I, subresource_range: ImageSubresourceRange) -> Self {
1021        Self(
1022            unsafe {
1023                ImageViewCreateInfo::from_raw(brvk::VkImageViewCreateInfo {
1024                    sType: brvk::VkImageViewCreateInfo::TYPE,
1025                    pNext: core::ptr::null(),
1026                    flags: 0,
1027                    image: source.native_ptr(),
1028                    viewType: source.dimension(),
1029                    format: source.format(),
1030                    components: brvk::VkComponentMapping {
1031                        r: brvk::VK_COMPONENT_SWIZZLE_R,
1032                        g: brvk::VK_COMPONENT_SWIZZLE_G,
1033                        b: brvk::VK_COMPONENT_SWIZZLE_B,
1034                        a: brvk::VK_COMPONENT_SWIZZLE_A,
1035                    },
1036                    subresourceRange: subresource_range.0,
1037                })
1038            },
1039            source,
1040        )
1041    }
1042
1043    pub const fn with_format_mutation(mut self, format: brvk::VkFormat) -> Self {
1044        self.0 = self.0.with_format_mutation(format);
1045        self
1046    }
1047
1048    pub const fn with_mapping(mut self, mapping: brvk::VkComponentMapping) -> Self {
1049        self.0 = self.0.with_mapping(mapping);
1050        self
1051    }
1052
1053    pub const fn with_dimension(mut self, dimension: brvk::VkImageViewType) -> Self {
1054        self.0 = self.0.with_dimension(dimension);
1055        self
1056    }
1057
1058    /// Create a new image view from an existing image
1059    /// # Failure
1060    /// On failure, this command returns
1061    ///
1062    /// * `brvk::VK_ERROR_OUT_OF_HOST_MEMORY`
1063    /// * `brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`
1064    /// * `brvk::VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR`
1065    #[implements]
1066    pub fn create(self) -> crate::Result<ImageViewObject<I>>
1067    where
1068        I: DeviceChild,
1069    {
1070        ImageViewObject::new(self.1, &self.0)
1071    }
1072}