vulk_ext/vkx/
image.rs

1use super::*;
2
3#[derive(Clone, Copy, Debug)]
4pub struct ImageCreator(vk::ImageCreateInfo);
5
6impl ImageCreator {
7    #[must_use]
8    pub fn new_2d(
9        width: u32,
10        height: u32,
11        format: vk::Format,
12        usage: impl Into<vk::ImageUsageFlags> + Copy,
13    ) -> Self {
14        Self(vk::ImageCreateInfo {
15            s_type: vk::StructureType::ImageCreateInfo,
16            p_next: null(),
17            flags: vk::ImageCreateFlags::empty(),
18            image_type: vk::ImageType::Type2d,
19            format,
20            extent: vk::Extent3D {
21                width,
22                height,
23                depth: 1,
24            },
25            mip_levels: 1,
26            array_layers: 1,
27            samples: vk::SampleCountFlagBits::Count1,
28            tiling: vk::ImageTiling::Optimal,
29            usage: usage.into(),
30            sharing_mode: vk::SharingMode::Exclusive,
31            queue_family_index_count: 0,
32            p_queue_family_indices: null(),
33            initial_layout: vk::ImageLayout::Undefined,
34        })
35    }
36
37    #[must_use]
38    pub fn new_2d_samples(
39        width: u32,
40        height: u32,
41        format: vk::Format,
42        usage: impl Into<vk::ImageUsageFlags> + Copy,
43        samples: vk::SampleCountFlagBits,
44    ) -> Self {
45        Self::new_2d(width, height, format, usage).samples(samples)
46    }
47
48    #[must_use]
49    pub fn samples(self, samples: vk::SampleCountFlagBits) -> Self {
50        Self(vk::ImageCreateInfo { samples, ..self.0 })
51    }
52
53    pub unsafe fn create(self, device: &Device) -> Result<(vk::Image, vk::ImageCreateInfo)> {
54        let image_create_info = self.0;
55        let image = device.create_image(&image_create_info)?;
56        Ok((image, image_create_info))
57    }
58}
59
60#[derive(Clone, Copy, Debug)]
61pub struct ImageViewCreator(vk::ImageViewCreateInfo);
62
63impl ImageViewCreator {
64    #[must_use]
65    pub fn new_2d(image: vk::Image, format: vk::Format) -> Self {
66        Self(vk::ImageViewCreateInfo {
67            s_type: vk::StructureType::ImageViewCreateInfo,
68            p_next: null(),
69            flags: vk::ImageViewCreateFlags::empty(),
70            image,
71            view_type: vk::ImageViewType::Type2d,
72            format,
73            components: vk::ComponentMapping {
74                r: vk::ComponentSwizzle::Identity,
75                g: vk::ComponentSwizzle::Identity,
76                b: vk::ComponentSwizzle::Identity,
77                a: vk::ComponentSwizzle::Identity,
78            },
79            subresource_range: vk::ImageSubresourceRange {
80                aspect_mask: format.aspect_mask(),
81                base_mip_level: 0,
82                level_count: 1,
83                base_array_layer: 0,
84                layer_count: 1,
85            },
86        })
87    }
88
89    pub unsafe fn create(
90        self,
91        device: &Device,
92    ) -> Result<(vk::ImageView, vk::ImageViewCreateInfo)> {
93        let image_view_create_info = self.0;
94        let image_view = device.create_image_view(&image_view_create_info)?;
95        Ok((image_view, image_view_create_info))
96    }
97}
98
99pub trait ImageOps {
100    fn image_handle(&self) -> vk::Image;
101
102    fn image_view_handle(&self) -> vk::ImageView;
103
104    fn image_create_info(&self) -> &vk::ImageCreateInfo;
105
106    fn image_view_create_info(&self) -> &vk::ImageViewCreateInfo;
107
108    fn descriptor(&self) -> Descriptor;
109
110    fn format(&self) -> vk::Format {
111        self.image_create_info().format
112    }
113
114    fn extent_2d(&self) -> vk::Extent2D {
115        vk::Extent2D {
116            width: self.extent_3d().width,
117            height: self.extent_3d().height,
118        }
119    }
120
121    fn extent_3d(&self) -> vk::Extent3D {
122        self.image_create_info().extent
123    }
124
125    fn width(&self) -> u32 {
126        self.extent_3d().width
127    }
128
129    fn height(&self) -> u32 {
130        self.extent_3d().height
131    }
132
133    fn depth(&self) -> u32 {
134        self.extent_3d().depth
135    }
136
137    fn byte_size(&self) -> vk::DeviceSize {
138        let block_size = vk::DeviceSize::from(self.format().block_size());
139        let width = vk::DeviceSize::from(self.width());
140        let height = vk::DeviceSize::from(self.height());
141        let depth = vk::DeviceSize::from(self.depth());
142        block_size * width * height * depth
143    }
144
145    fn rect_2d(&self) -> vk::Rect2D {
146        vk::Rect2D {
147            offset: vk::Offset2D { x: 0, y: 0 },
148            extent: self.extent_2d(),
149        }
150    }
151
152    fn subresource_range(&self) -> vk::ImageSubresourceRange {
153        self.image_view_create_info().subresource_range
154    }
155
156    fn subresource_layers(&self) -> vk::ImageSubresourceLayers {
157        let subresource_range = self.subresource_range();
158        vk::ImageSubresourceLayers {
159            aspect_mask: subresource_range.aspect_mask,
160            mip_level: 0,
161            base_array_layer: subresource_range.base_array_layer,
162            layer_count: subresource_range.layer_count,
163        }
164    }
165}
166
167/// [`ImageResource`] is meant to be used by a shader.
168#[derive(Debug)]
169pub struct ImageResource {
170    image: vk::Image,
171    image_view: vk::ImageView,
172    image_create_info: vk::ImageCreateInfo,
173    image_view_create_info: vk::ImageViewCreateInfo,
174    descriptor: Descriptor,
175}
176
177impl ImageResource {
178    pub unsafe fn create(
179        physical_device: &PhysicalDevice,
180        device: &Device,
181        image_creators: &[ImageCreator],
182        property_flags: impl Into<vk::MemoryPropertyFlags> + Copy,
183    ) -> Result<(Vec<Self>, ImageAllocations)> {
184        // Constants.
185        const SAMPLED_IMAGE: vk::ImageUsageFlagBits = vk::ImageUsageFlagBits::Sampled;
186        const STORAGE_IMAGE: vk::ImageUsageFlagBits = vk::ImageUsageFlagBits::Storage;
187        const INPUT_ATTACHMENT: vk::ImageUsageFlagBits = vk::ImageUsageFlagBits::InputAttachment;
188
189        // Images.
190        let mut images = Vec::with_capacity(image_creators.len());
191        let mut image_create_infos = Vec::with_capacity(image_creators.len());
192        for &image_creator in image_creators {
193            let (image, image_create_info) = image_creator.create(device)?;
194            images.push(image);
195            image_create_infos.push(image_create_info);
196        }
197
198        // Image allocations.
199        let image_allocations = ImageAllocations::allocate(
200            physical_device,
201            device,
202            &images,
203            &image_create_infos,
204            property_flags,
205        )?;
206
207        // Image views.
208        let mut image_views = Vec::with_capacity(image_creators.len());
209        let mut image_view_create_infos = Vec::with_capacity(image_creators.len());
210        for (&image, image_create_info) in images.iter().zip(&image_create_infos) {
211            let (image_view, image_view_create_info) =
212                ImageViewCreator::new_2d(image, image_create_info.format).create(device)?;
213            image_views.push(image_view);
214            image_view_create_infos.push(image_view_create_info);
215        }
216
217        // Descriptors.
218        let mut descriptors = Vec::with_capacity(image_creators.len());
219        for (&image_view, image_create_info) in image_views.iter().zip(&image_create_infos) {
220            let usage = image_create_info.usage;
221            let descriptor = if usage.contains(SAMPLED_IMAGE) {
222                Descriptor::create(
223                    physical_device,
224                    device,
225                    DescriptorCreateInfo::SampledImage {
226                        image_view,
227                        image_layout: vk::ImageLayout::ReadOnlyOptimal,
228                    },
229                )
230            } else if usage.contains(STORAGE_IMAGE) {
231                Descriptor::create(
232                    physical_device,
233                    device,
234                    DescriptorCreateInfo::StorageImage {
235                        image_view,
236                        image_layout: vk::ImageLayout::General,
237                    },
238                )
239            } else if usage.contains(INPUT_ATTACHMENT) {
240                Descriptor::create(
241                    physical_device,
242                    device,
243                    DescriptorCreateInfo::InputAttachment {
244                        image_view,
245                        image_layout: vk::ImageLayout::ReadOnlyOptimal,
246                    },
247                )
248            } else {
249                bail!(
250                    "Image resource must be \
251                    {SAMPLED_IMAGE} or \
252                    {STORAGE_IMAGE} or \
253                    {INPUT_ATTACHMENT}, \
254                    got {usage}"
255                );
256            };
257            descriptors.push(descriptor);
258        }
259
260        // Resources.
261        let mut image_resources = Vec::with_capacity(image_creators.len());
262        for i in 0..image_creators.len() {
263            let image = images[i];
264            let image_create_info = image_create_infos[i];
265            let image_view = image_views[i];
266            let image_view_create_info = image_view_create_infos[i];
267            let descriptor = descriptors[i];
268            image_resources.push(Self {
269                image,
270                image_view,
271                image_create_info,
272                image_view_create_info,
273                descriptor,
274            });
275        }
276        Ok((image_resources, image_allocations))
277    }
278
279    pub unsafe fn destroy(self, device: &Device) {
280        device.destroy_image_view(self.image_view);
281        device.destroy_image(self.image);
282    }
283}
284
285impl ImageOps for ImageResource {
286    fn image_handle(&self) -> vk::Image {
287        self.image
288    }
289
290    fn image_view_handle(&self) -> vk::ImageView {
291        self.image_view
292    }
293
294    fn image_create_info(&self) -> &vk::ImageCreateInfo {
295        &self.image_create_info
296    }
297
298    fn image_view_create_info(&self) -> &vk::ImageViewCreateInfo {
299        &self.image_view_create_info
300    }
301
302    fn descriptor(&self) -> Descriptor {
303        self.descriptor
304    }
305}
306
307/// [`ImageDedicatedResource`] trades off allocation efficiency for ease of use.
308#[derive(Debug)]
309pub struct ImageDedicatedResource {
310    image_resource: ImageResource,
311    image_allocations: ImageAllocations,
312}
313
314impl ImageDedicatedResource {
315    pub unsafe fn create_2d(
316        physical_device: &PhysicalDevice,
317        device: &Device,
318        image_creator: ImageCreator,
319        property_flags: impl Into<vk::MemoryPropertyFlags> + Copy,
320    ) -> Result<Self> {
321        let (mut image_resources, image_allocations) =
322            ImageResource::create(physical_device, device, &[image_creator], property_flags)?;
323        let image_resource = image_resources.swap_remove(0);
324        Ok(Self {
325            image_resource,
326            image_allocations,
327        })
328    }
329
330    pub unsafe fn destroy(self, device: &Device) {
331        self.image_resource.destroy(device);
332        self.image_allocations.free(device);
333    }
334}
335
336impl ImageOps for ImageDedicatedResource {
337    fn image_handle(&self) -> vk::Image {
338        self.image_resource.image
339    }
340
341    fn image_view_handle(&self) -> vk::ImageView {
342        self.image_resource.image_view
343    }
344
345    fn image_create_info(&self) -> &vk::ImageCreateInfo {
346        &self.image_resource.image_create_info
347    }
348
349    fn image_view_create_info(&self) -> &vk::ImageViewCreateInfo {
350        &self.image_resource.image_view_create_info
351    }
352
353    fn descriptor(&self) -> Descriptor {
354        self.image_resource.descriptor
355    }
356}