voodoo/
image.rs

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    /// Returns this object's handle.
22    #[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/// An image.
49///
50///
51/// ### Destruction
52/// 
53/// Dropping this `Image` will cause `Device::destroy_image` to be called, 
54/// automatically releasing any resources associated with it.
55///
56#[derive(Debug, Clone)]
57pub struct Image {
58    inner: Arc<Inner>,
59}
60
61impl Image {
62    /// Returns a new `ImageBuilder`.
63    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    /// Returns this object's handle.
81    pub fn handle(&self) -> ImageHandle {
82        self.inner.handle
83    }
84
85    /// Returns this image's memory requirements.
86    pub fn memory_requirements(&self) -> &::MemoryRequirements {
87        &self.inner.memory_requirements
88    }
89
90    /// Binds this image to device memory. `offset` is the start offset of the
91    /// region of memory which is to be bound. The number of bytes returned in
92    /// the VkMemoryRequirements::size member in memory, starting from
93    /// memoryOffset bytes, will be bound to the specified image.
94    ///
95    /// ## Safety
96    ///
97    /// The caller must ensure that the bound memory is not in use when it is
98    /// dropped.
99    ///
100    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    /// Returns a reference to the associated device.
106    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/// A builder for `Image`.
122#[derive(Debug, Clone)]
123pub struct ImageBuilder<'b> {
124    create_info: ::ImageCreateInfo<'b>,
125    _p: PhantomData<&'b ()>,
126}
127
128impl<'b> ImageBuilder<'b> {
129    /// Returns a new render pass builder.
130    pub fn new() -> ImageBuilder<'b> {
131        ImageBuilder {
132            create_info: ::ImageCreateInfo::default(),
133            _p: PhantomData,
134        }
135    }
136
137    /// flags is a bitmask of VkImageCreateFlagBits describing additional
138    /// parameters of the image.
139    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    /// imageType is a VkImageType value specifying the basic dimensionality
146    /// of the image. Layers in array textures do not count as a dimension for
147    /// the purposes of the image type.
148    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    /// format is a VkFormat describing the format and type of the data
155    /// elements that will be contained in the image.
156    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    /// extent is a VkExtent3D describing the number of data elements in each
163    /// dimension of the base level.
164    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    /// mipLevels describes the number of levels of detail available for
171    /// minified sampling of the image.
172    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    /// arrayLayers is the number of layers in the image.
179    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    /// samples is the number of sub-data element samples in the image as
186    /// defined in VkSampleCountFlagBits. See Multisampling.
187    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    /// tiling is a VkImageTiling value specifying the tiling arrangement of
194    /// the data elements in memory.
195    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    /// usage is a bitmask of VkImageUsageFlagBits describing the intended
202    /// usage of the image.
203    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    /// sharingMode is a VkSharingMode value specifying the sharing mode of
210    /// the image when it will be accessed by multiple queue families.
211    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    /// queueFamilyIndexCount is the number of entries in the
218    /// pQueueFamilyIndices array.
219    /// pQueueFamilyIndices is a list of queue families that will access this
220    /// image (ignored if sharingMode is not VK_SHARING_MODE_CONCURRENT).
221    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    /// initialLayout is a VkImageLayout value specifying the initial
230    /// VkImageLayout of all image subresources of the image. See Image
231    /// Layouts.
232    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    //// Creates and returns a new `Image`
239    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}