1use std::sync::Arc;
2use std::marker::PhantomData;
3use vks;
4use ::{VdResult, Device, DeviceMemory, Handle};
5
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8#[repr(C)]
9pub struct ImageHandle(pub(crate) vks::VkImage);
10
11impl ImageHandle {
12 #[inline(always)]
13 pub fn to_raw(&self) -> vks::VkImage {
14 self.0
15 }
16}
17
18unsafe impl Handle for ImageHandle {
19 type Target = ImageHandle;
20
21 #[inline(always)]
23 fn handle(&self) -> Self::Target {
24 *self
25 }
26}
27
28
29#[derive(Debug)]
30struct Inner {
31 handle: ImageHandle,
32 memory_requirements: ::MemoryRequirements,
33 device: Device,
34 is_swapchain_image: bool,
35}
36
37impl Drop for Inner {
38 fn drop(&mut self) {
39 unsafe {
40 if !self.is_swapchain_image {
41 self.device.destroy_image(self.handle, None);
42 }
43 }
44 }
45}
46
47
48#[derive(Debug, Clone)]
57pub struct Image {
58 inner: Arc<Inner>,
59}
60
61impl Image {
62 pub fn builder<'b>() -> ImageBuilder<'b> {
64 ImageBuilder::new()
65 }
66
67 pub(crate) unsafe fn from_handle(device: Device, handle: ImageHandle, is_swapchain_image: bool) -> Image {
68 let memory_requirements = device.get_image_memory_requirements(handle);
69
70 Image {
71 inner: Arc::new(Inner {
72 handle,
73 memory_requirements: memory_requirements.into(),
74 device,
75 is_swapchain_image,
76 })
77 }
78 }
79
80 pub fn handle(&self) -> ImageHandle {
82 self.inner.handle
83 }
84
85 pub fn memory_requirements(&self) -> &::MemoryRequirements {
87 &self.inner.memory_requirements
88 }
89
90 pub unsafe fn bind_memory(&self, memory: &DeviceMemory, offset_bytes: ::DeviceSize)
101 -> VdResult<()> {
102 self.inner.device.bind_image_memory(self.inner.handle, memory.handle(), offset_bytes)
103 }
104
105 pub fn device(&self) -> &Device {
107 &self.inner.device
108 }
109}
110
111unsafe impl<'i> Handle for &'i Image {
112 type Target = ImageHandle;
113
114 #[inline(always)]
115 fn handle(&self) -> Self::Target {
116 self.inner.handle
117 }
118}
119
120
121#[derive(Debug, Clone)]
123pub struct ImageBuilder<'b> {
124 create_info: ::ImageCreateInfo<'b>,
125 _p: PhantomData<&'b ()>,
126}
127
128impl<'b> ImageBuilder<'b> {
129 pub fn new() -> ImageBuilder<'b> {
131 ImageBuilder {
132 create_info: ::ImageCreateInfo::default(),
133 _p: PhantomData,
134 }
135 }
136
137 pub fn flags<'s>(&'s mut self, flags: ::ImageCreateFlags)
140 -> &'s mut ImageBuilder<'b> {
141 self.create_info.set_flags(flags);
142 self
143 }
144
145 pub fn image_type<'s>(&'s mut self, image_type: ::ImageType)
149 -> &'s mut ImageBuilder<'b> {
150 self.create_info.set_image_type(image_type);
151 self
152 }
153
154 pub fn format<'s>(&'s mut self, format: ::Format)
157 -> &'s mut ImageBuilder<'b> {
158 self.create_info.set_format(format);
159 self
160 }
161
162 pub fn extent<'s>(&'s mut self, extent: ::Extent3d)
165 -> &'s mut ImageBuilder<'b> {
166 self.create_info.set_extent(extent);
167 self
168 }
169
170 pub fn mip_levels<'s>(&'s mut self, mip_levels: u32)
173 -> &'s mut ImageBuilder<'b> {
174 self.create_info.set_mip_levels(mip_levels);
175 self
176 }
177
178 pub fn array_layers<'s>(&'s mut self, array_layers: u32)
180 -> &'s mut ImageBuilder<'b> {
181 self.create_info.set_array_layers(array_layers);
182 self
183 }
184
185 pub fn samples<'s>(&'s mut self, samples: ::SampleCountFlags)
188 -> &'s mut ImageBuilder<'b> {
189 self.create_info.set_samples(samples);
190 self
191 }
192
193 pub fn tiling<'s>(&'s mut self, tiling: ::ImageTiling)
196 -> &'s mut ImageBuilder<'b> {
197 self.create_info.set_tiling(tiling);
198 self
199 }
200
201 pub fn usage<'s>(&'s mut self, usage: ::ImageUsageFlags)
204 -> &'s mut ImageBuilder<'b> {
205 self.create_info.set_usage(usage);
206 self
207 }
208
209 pub fn sharing_mode<'s>(&'s mut self, sharing_mode: ::SharingMode)
212 -> &'s mut ImageBuilder<'b> {
213 self.create_info.set_sharing_mode(sharing_mode);
214 self
215 }
216
217 pub fn queue_family_indices<'s, 'p>(&'s mut self,
222 queue_family_indices: &'p [u32])
223 -> &'s mut ImageBuilder<'b>
224 where 'p: 'b {
225 self.create_info.set_queue_family_indices(queue_family_indices);
226 self
227 }
228
229 pub fn initial_layout<'s>(&'s mut self, initial_layout: ::ImageLayout)
233 -> &'s mut ImageBuilder<'b> {
234 self.create_info.set_initial_layout(initial_layout);
235 self
236 }
237
238 pub fn build(&self, device: Device) -> VdResult<Image> {
240 unsafe {
241 let handle = device.create_image(&self.create_info, None)?;
242 Ok(Image::from_handle(device, handle, false))
243 }
244 }
245}