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#[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 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 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 let image_allocations = ImageAllocations::allocate(
200 physical_device,
201 device,
202 &images,
203 &image_create_infos,
204 property_flags,
205 )?;
206
207 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 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 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#[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}