bort_vk/
image_view.rs

1use crate::{Device, DeviceOwned, ImageAccess, ImageProperties, ALLOCATION_CALLBACK_NONE};
2use ash::{
3    prelude::VkResult,
4    vk::{self, Handle},
5};
6use std::sync::Arc;
7
8/// Unifies image views with different types of images
9pub trait ImageViewAccess: DeviceOwned + Send + Sync {
10    fn handle(&self) -> vk::ImageView;
11    fn image_access(&self) -> Arc<dyn ImageAccess>;
12}
13
14pub struct ImageView<I: ImageAccess + 'static> {
15    handle: vk::ImageView,
16    properties: ImageViewProperties,
17
18    // dependencies
19    image: Arc<I>,
20}
21
22impl<I: ImageAccess + 'static> ImageView<I> {
23    pub fn new(image: Arc<I>, properties: ImageViewProperties) -> VkResult<Self> {
24        let create_info_builder = properties.create_info_builder(image.handle());
25
26        let handle = unsafe {
27            image
28                .device()
29                .inner()
30                .create_image_view(&create_info_builder, ALLOCATION_CALLBACK_NONE)
31        }?;
32
33        Ok(Self {
34            handle,
35            properties,
36            image,
37        })
38    }
39
40    pub unsafe fn new_from_create_info(
41        image: Arc<I>,
42        create_info_builder: vk::ImageViewCreateInfoBuilder,
43    ) -> VkResult<Self> {
44        let properties = ImageViewProperties::from_create_info_builder(&create_info_builder);
45
46        let handle = unsafe {
47            image
48                .device()
49                .inner()
50                .create_image_view(&create_info_builder, ALLOCATION_CALLBACK_NONE)
51        }?;
52
53        Ok(Self {
54            handle,
55            properties,
56            image,
57        })
58    }
59
60    // Getters
61
62    pub fn properties(&self) -> &ImageViewProperties {
63        &self.properties
64    }
65
66    pub fn image(&self) -> &Arc<I> {
67        &self.image
68    }
69}
70
71impl<I: ImageAccess + 'static> ImageViewAccess for ImageView<I> {
72    fn handle(&self) -> vk::ImageView {
73        self.handle
74    }
75
76    fn image_access(&self) -> Arc<dyn ImageAccess> {
77        self.image.clone()
78    }
79}
80
81impl<I: ImageAccess + 'static> DeviceOwned for ImageView<I> {
82    #[inline]
83    fn device(&self) -> &Arc<Device> {
84        self.image.device()
85    }
86
87    #[inline]
88    fn handle_raw(&self) -> u64 {
89        self.handle.as_raw()
90    }
91}
92
93impl<I: ImageAccess + 'static> Drop for ImageView<I> {
94    fn drop(&mut self) {
95        unsafe {
96            self.device()
97                .inner()
98                .destroy_image_view(self.handle, ALLOCATION_CALLBACK_NONE);
99        }
100    }
101}
102
103/// WARNING `default()` values for `format`, `view_type` are nothing!
104#[derive(Debug, Copy, Clone)]
105pub struct ImageViewProperties {
106    pub flags: vk::ImageViewCreateFlags,
107    pub view_type: vk::ImageViewType,
108    pub component_mapping: vk::ComponentMapping,
109    pub format: vk::Format,
110    pub subresource_range: vk::ImageSubresourceRange,
111}
112
113impl Default for ImageViewProperties {
114    fn default() -> Self {
115        Self {
116            component_mapping: default_component_mapping(),
117            flags: vk::ImageViewCreateFlags::empty(),
118            subresource_range: default_subresource_range(vk::ImageAspectFlags::COLOR),
119
120            // nonsense defaults. make sure you override these!
121            format: vk::Format::default(),
122            view_type: vk::ImageViewType::default(),
123        }
124    }
125}
126
127impl ImageViewProperties {
128    pub fn from_image_properties_default(image_properties: &ImageProperties) -> Self {
129        let format = image_properties.format;
130        let view_type = image_properties.dimensions.default_image_view_type();
131        let subresource_range = image_properties.subresource_range();
132
133        Self {
134            format,
135            subresource_range,
136            view_type,
137            ..Self::default()
138        }
139    }
140
141    pub fn write_create_info_builder<'a>(
142        &'a self,
143        builder: vk::ImageViewCreateInfoBuilder<'a>,
144        image_handle: vk::Image,
145    ) -> vk::ImageViewCreateInfoBuilder {
146        builder
147            .flags(self.flags)
148            .image(image_handle)
149            .view_type(self.view_type)
150            .format(self.format)
151            .components(self.component_mapping)
152            .subresource_range(self.subresource_range)
153    }
154
155    pub fn create_info_builder(&self, image_handle: vk::Image) -> vk::ImageViewCreateInfoBuilder {
156        self.write_create_info_builder(vk::ImageViewCreateInfo::builder(), image_handle)
157    }
158
159    pub fn from_create_info_builder(create_info: &vk::ImageViewCreateInfoBuilder) -> Self {
160        Self {
161            flags: create_info.flags,
162            view_type: create_info.view_type,
163            component_mapping: create_info.components,
164            format: create_info.format,
165            subresource_range: create_info.subresource_range,
166        }
167    }
168}
169
170// Helper Functions
171
172pub fn default_component_mapping() -> vk::ComponentMapping {
173    vk::ComponentMapping {
174        r: vk::ComponentSwizzle::R,
175        g: vk::ComponentSwizzle::G,
176        b: vk::ComponentSwizzle::B,
177        a: vk::ComponentSwizzle::A,
178    }
179}
180
181pub fn default_subresource_range(aspect_mask: vk::ImageAspectFlags) -> vk::ImageSubresourceRange {
182    vk::ImageSubresourceRange {
183        aspect_mask,
184        base_mip_level: 0,
185        level_count: 1,
186        base_array_layer: 0,
187        layer_count: 1,
188    }
189}
190
191pub fn default_subresource_layers(aspect_mask: vk::ImageAspectFlags) -> vk::ImageSubresourceLayers {
192    vk::ImageSubresourceLayers {
193        aspect_mask,
194        mip_level: 0,
195        base_array_layer: 0,
196        layer_count: 1,
197    }
198}