1use crate::{Device, DeviceOwned, ImageAccess, ImageProperties, ALLOCATION_CALLBACK_NONE};
2use ash::{
3 prelude::VkResult,
4 vk::{self, Handle},
5};
6use std::sync::Arc;
7
8pub 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 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 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#[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 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
170pub 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}