1use crate::*;
2use derives::implements;
3
4pub trait DeviceMemory: VkHandle<Handle = VkDeviceMemory> + DeviceChildHandle {
5 #[implements]
7 #[inline]
8 fn commitment_bytes(&self) -> VkDeviceSize {
9 let mut b = 0;
10 unsafe {
11 crate::vkfn::get_device_memory_commitment(self.device_handle(), self.native_ptr(), &mut b);
12 }
13
14 b
15 }
16}
17DerefContainerBracketImpl!(for DeviceMemory {});
18GuardsImpl!(for DeviceMemory {});
19
20pub trait DeviceMemoryMut: DeviceMemory + VkHandleMut {
21 #[implements]
31 #[inline]
32 unsafe fn map_raw(&mut self, range: core::ops::Range<VkDeviceSize>) -> crate::Result<*mut core::ffi::c_void> {
33 let mut p = core::mem::MaybeUninit::uninit();
34
35 unsafe {
36 crate::vkfn::map_memory(
37 self.device_handle(),
38 self.native_ptr_mut(),
39 range.start,
40 range.end - range.start,
41 0,
42 p.as_mut_ptr(),
43 )
44 .into_result()?;
45 }
46
47 Ok(unsafe { p.assume_init() })
48 }
49
50 #[implements]
58 fn map(&mut self, range: core::ops::Range<usize>) -> crate::Result<MappedMemory<Self>> {
59 let p = unsafe { self.map_raw(range.start as _..range.end as _)? };
60
61 Ok(MappedMemory(p, self))
62 }
63
64 #[implements]
69 #[inline]
70 unsafe fn unmap(&mut self) {
71 unsafe { crate::vkfn::unmap_memory(self.device_handle(), self.native_ptr_mut()) }
72 }
73}
74DerefContainerBracketImpl!(for mut DeviceMemoryMut {});
75GuardsImpl!(for mut DeviceMemoryMut {});
76
77#[derive(VkHandle, VkObject)]
78#[VkObject(type = VkDeviceMemory::OBJECT_TYPE)]
79pub struct DeviceMemoryObject<Device: VkHandle<Handle = VkDevice>>(VkDeviceMemory, Device);
80#[implements]
81impl<Device: VkHandle<Handle = VkDevice>> Drop for DeviceMemoryObject<Device> {
82 #[inline(always)]
83 fn drop(&mut self) {
84 unsafe {
85 crate::vkfn::free_memory(self.1.native_ptr(), self.0, core::ptr::null());
86 }
87 }
88}
89unsafe impl<Device: VkHandle<Handle = VkDevice> + Sync> Sync for DeviceMemoryObject<Device> {}
90unsafe impl<Device: VkHandle<Handle = VkDevice> + Send> Send for DeviceMemoryObject<Device> {}
91impl<Device: VkHandle<Handle = VkDevice>> DeviceChildHandle for DeviceMemoryObject<Device> {
92 #[inline(always)]
93 fn device_handle(&self) -> VkDevice {
94 self.1.native_ptr()
95 }
96}
97impl<Device: crate::Device> DeviceChild for DeviceMemoryObject<Device> {
98 type ConcreteDevice = Device;
99
100 #[inline(always)]
101 fn device(&self) -> &Self::ConcreteDevice {
102 &self.1
103 }
104}
105impl<Device: VkHandle<Handle = VkDevice>> DeviceMemory for DeviceMemoryObject<Device> {}
106impl<Device: VkHandle<Handle = VkDevice>> DeviceMemoryMut for DeviceMemoryObject<Device> {}
107impl<Device: VkHandle<Handle = VkDevice>> DeviceMemoryObject<Device> {
108 pub const unsafe fn manage(handle: VkDeviceMemory, parent: Device) -> Self {
112 Self(handle, parent)
113 }
114
115 pub const fn unmanage(self) -> (VkDeviceMemory, Device) {
117 let v = self.0;
118 let p = unsafe { core::ptr::read(&self.1) };
119 core::mem::forget(self);
120
121 (v, p)
122 }
123}
124impl<Device: VkHandle<Handle = VkDevice> + Clone> DeviceMemoryObject<&'_ Device> {
125 #[inline(always)]
127 pub fn clone_parent(self) -> DeviceMemoryObject<Device> {
128 let r = DeviceMemoryObject(self.0, self.1.clone());
129 core::mem::forget(self);
130
131 r
132 }
133}
134impl<Device: crate::Device> DeviceMemoryObject<Device> {
135 #[implements]
144 #[inline]
145 pub fn new(device: Device, info: &MemoryAllocateInfo) -> crate::Result<Self> {
146 Ok(unsafe { Self::manage(device.allocate_memory(info, None)?, device) })
147 }
148}
149
150#[repr(transparent)]
152#[derive(Clone)]
153pub struct MemoryAllocateInfo<'d>(
154 VkMemoryAllocateInfo,
155 core::marker::PhantomData<Option<&'d dyn VulkanStructure>>,
156);
157impl<'d> MemoryAllocateInfo<'d> {
158 pub const fn new(size: VkDeviceSize, memory_type_index: u32) -> Self {
159 Self(
160 VkMemoryAllocateInfo {
161 sType: VkMemoryAllocateInfo::TYPE,
162 pNext: core::ptr::null(),
163 allocationSize: size,
164 memoryTypeIndex: memory_type_index,
165 },
166 core::marker::PhantomData,
167 )
168 }
169
170 pub const unsafe fn from_raw(raw: VkMemoryAllocateInfo) -> Self {
171 Self(raw, core::marker::PhantomData)
172 }
173
174 pub const fn into_raw(self) -> VkMemoryAllocateInfo {
175 self.0
176 }
177
178 pub const fn with_next(mut self, next: &'d (impl VulkanStructure + ?Sized)) -> Self {
179 self.0.pNext = next as *const _ as _;
180 self
181 }
182
183 pub const unsafe fn next_sink<T: VulkanStructure>(&mut self) -> &mut *const T {
184 unsafe { core::mem::transmute(&mut self.0.pNext) }
185 }
186}
187
188#[cfg(feature = "VK_KHR_dedicated_allocation")]
190#[repr(transparent)]
191#[derive(Clone)]
192pub struct MemoryDedicatedAllocateInfo<'d>(
193 VkMemoryDedicatedAllocateInfoKHR,
194 core::marker::PhantomData<(
195 Option<&'d dyn VulkanStructure>,
196 Option<&'d dyn VkHandle<Handle = VkImage>>,
197 Option<&'d dyn VkHandle<Handle = VkBuffer>>,
198 )>,
199);
200#[cfg(feature = "VK_KHR_dedicated_allocation")]
201unsafe impl VulkanStructure for MemoryDedicatedAllocateInfo<'_> {
202 #[inline(always)]
203 fn as_generic(&self) -> &GenericVulkanStructure {
204 unsafe { core::mem::transmute(self) }
205 }
206
207 #[inline(always)]
208 fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
209 unsafe { core::mem::transmute(self) }
210 }
211}
212#[cfg(feature = "VK_KHR_dedicated_allocation")]
213impl<'d> MemoryDedicatedAllocateInfo<'d> {
214 #[inline]
215 pub fn for_buffer(buffer: &'d (impl VkHandle<Handle = VkBuffer> + ?Sized)) -> Self {
216 Self(
217 VkMemoryDedicatedAllocateInfoKHR {
218 sType: VkMemoryDedicatedAllocateInfoKHR::TYPE,
219 pNext: core::ptr::null(),
220 image: VkImage::NULL,
221 buffer: buffer.native_ptr(),
222 },
223 core::marker::PhantomData,
224 )
225 }
226
227 #[inline]
228 pub const unsafe fn for_buffer_raw(buffer: VkBuffer) -> Self {
229 Self(
230 VkMemoryDedicatedAllocateInfoKHR {
231 sType: VkMemoryDedicatedAllocateInfoKHR::TYPE,
232 pNext: core::ptr::null(),
233 image: VkImage::NULL,
234 buffer,
235 },
236 core::marker::PhantomData,
237 )
238 }
239
240 #[inline]
241 pub fn for_image(image: &'d (impl VkHandle<Handle = VkImage> + ?Sized)) -> Self {
242 Self(
243 VkMemoryDedicatedAllocateInfoKHR {
244 sType: VkMemoryDedicatedAllocateInfoKHR::TYPE,
245 pNext: core::ptr::null(),
246 image: image.native_ptr(),
247 buffer: VkBuffer::NULL,
248 },
249 core::marker::PhantomData,
250 )
251 }
252
253 #[inline]
254 pub const unsafe fn for_image_raw(image: VkImage) -> Self {
255 Self(
256 VkMemoryDedicatedAllocateInfoKHR {
257 sType: VkMemoryDedicatedAllocateInfoKHR::TYPE,
258 pNext: core::ptr::null(),
259 image,
260 buffer: VkBuffer::NULL,
261 },
262 core::marker::PhantomData,
263 )
264 }
265
266 pub const unsafe fn from_raw(raw: VkMemoryDedicatedAllocateInfoKHR) -> Self {
267 Self(raw, core::marker::PhantomData)
268 }
269
270 pub const fn into_raw(self) -> VkMemoryDedicatedAllocateInfoKHR {
271 self.0
272 }
273
274 pub const fn with_next(mut self, next: &'d (impl VulkanStructure + ?Sized)) -> Self {
275 self.0.pNext = next as *const _ as _;
276 self
277 }
278
279 pub const unsafe fn next_sink<T: VulkanStructure>(&mut self) -> &mut *const T {
280 unsafe { core::mem::transmute(&mut self.0.pNext) }
281 }
282}
283
284pub struct MappedMemoryRange<'a>(
286 VkMappedMemoryRange,
287 core::marker::PhantomData<&'a dyn VkHandle<Handle = VkDeviceMemory>>,
288);
289impl<'a> MappedMemoryRange<'a> {
290 pub fn new(
291 memory: &'a (impl VkHandle<Handle = VkDeviceMemory> + ?Sized),
292 range: core::ops::Range<DeviceSize>,
293 ) -> Self {
294 Self(
295 VkMappedMemoryRange {
296 sType: VkMappedMemoryRange::TYPE,
297 pNext: core::ptr::null(),
298 memory: memory.native_ptr(),
299 offset: range.start,
300 size: range.end - range.start,
301 },
302 core::marker::PhantomData,
303 )
304 }
305
306 pub const unsafe fn new_raw(memory: VkDeviceMemory, offset: DeviceSize, size: DeviceSize) -> Self {
307 Self(
308 VkMappedMemoryRange {
309 sType: VkMappedMemoryRange::TYPE,
310 pNext: core::ptr::null(),
311 memory,
312 offset,
313 size,
314 },
315 core::marker::PhantomData,
316 )
317 }
318
319 pub const unsafe fn from_raw(raw: VkMappedMemoryRange) -> Self {
320 Self(raw, core::marker::PhantomData)
321 }
322
323 pub const fn into_raw(self) -> VkMappedMemoryRange {
324 self.0
325 }
326}
327
328pub struct MappedMemory<'m, DeviceMemory: crate::DeviceMemoryMut + ?Sized + 'm>(
330 *mut core::ffi::c_void,
331 &'m mut DeviceMemory,
332);
333#[allow(clippy::mut_from_ref)]
334impl<'m, DeviceMemory: crate::DeviceMemoryMut + ?Sized + 'm> MappedMemory<'m, DeviceMemory> {
335 pub const fn ptr(&self) -> *mut core::ffi::c_void {
337 self.0
338 }
339
340 pub const unsafe fn addr_of_mut<T>(&self, offset: usize) -> *mut T {
344 unsafe { self.0.byte_add(offset) as *mut T }
345 }
346
347 pub const unsafe fn get<T>(&self, offset: usize) -> &T {
351 unsafe { &*(self.0.byte_add(offset) as *const T) }
352 }
353
354 pub const unsafe fn get_mut<T>(&self, offset: usize) -> &mut T {
358 unsafe { &mut *(self.0.byte_add(offset) as *mut T) }
359 }
360
361 pub const unsafe fn slice<T>(&self, offset: usize, count: usize) -> &[T] {
365 unsafe { core::slice::from_raw_parts(self.0.byte_add(offset) as *const T, count) }
366 }
367
368 pub const unsafe fn slice_mut<T>(&self, offset: usize, count: usize) -> &mut [T] {
372 unsafe { core::slice::from_raw_parts_mut(self.0.byte_add(offset) as *mut T, count) }
373 }
374
375 #[inline(always)]
379 pub unsafe fn clone_from_slice_at<T: Clone>(&self, offset: usize, src: &[T]) {
380 unsafe { self.slice_mut(offset, src.len()).clone_from_slice(src) };
381 }
382
383 #[inline(always)]
387 pub unsafe fn clone_at<T: Clone>(&self, offset: usize, src: &T) {
388 unsafe { *self.get_mut(offset) = src.clone() };
389 }
390
391 #[implements]
392 pub fn end(self) {
394 unsafe {
395 self.1.unmap();
396 }
397 }
398}