1use bedrock_vk::{self as brvk, TypedVulkanStructure, VkRawHandle};
2
3use crate::*;
4use derives::implements;
5
6pub trait DeviceMemory: VkHandle<Handle = brvk::VkDeviceMemory> + DeviceChildHandle {
7 #[implements]
9 #[inline]
10 fn commitment_bytes(&self) -> brvk::VkDeviceSize {
11 let mut b = 0;
12 unsafe {
13 brvk::fns::get_device_memory_commitment(self.device_handle(), self.native_ptr(), &mut b);
14 }
15
16 b
17 }
18}
19DerefContainerBracketImpl!(for DeviceMemory {});
20GuardsImpl!(for DeviceMemory {});
21
22pub trait DeviceMemoryMut: DeviceMemory + VkHandleMut {
23 #[implements]
33 #[inline(always)]
34 unsafe fn map_raw(&mut self, range: core::ops::Range<DeviceSize>) -> crate::Result<*mut core::ffi::c_void> {
35 unsafe {
36 crate::vkfn_wrapper::map_memory(
37 self.device_transparent_ref(),
38 VkHandleRefMut::dangling(self.native_ptr()),
39 range,
40 0,
41 )
42 }
43 }
44
45 #[implements]
53 #[inline]
54 fn map<'a>(&'a mut self, range: core::ops::Range<usize>) -> crate::Result<MappedMemory<'a, Self>> {
55 Ok(MappedMemory(
56 unsafe { self.map_raw(range.start as _..range.end as _)? },
57 self,
58 ))
59 }
60
61 #[implements]
66 #[inline(always)]
67 unsafe fn unmap(&mut self) {
68 unsafe {
69 crate::vkfn_wrapper::unmap_memory(
70 self.device_transparent_ref(),
71 VkHandleRefMut::dangling(self.native_ptr()),
72 )
73 }
74 }
75}
76DerefContainerBracketImpl!(for mut DeviceMemoryMut {});
77GuardsImpl!(for mut DeviceMemoryMut {});
78
79#[derive(VkHandle, VkObject)]
80#[VkObject(type = brvk::VkDeviceMemory::OBJECT_TYPE)]
81pub struct DeviceMemoryObject<Device: VkHandle<Handle = brvk::VkDevice>>(brvk::VkDeviceMemory, Device);
82#[implements]
83impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for DeviceMemoryObject<Device> {
84 #[inline(always)]
85 fn drop(&mut self) {
86 unsafe {
87 crate::vkfn_wrapper::free_memory(self.device_transparent_ref(), VkHandleRefMut::dangling(self.0), None);
88 }
89 }
90}
91unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for DeviceMemoryObject<Device> {}
92unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for DeviceMemoryObject<Device> {}
93impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for DeviceMemoryObject<Device> {
94 #[inline(always)]
95 fn device_handle(&self) -> brvk::VkDevice {
96 self.1.native_ptr()
97 }
98}
99impl<Device: crate::Device> DeviceChild for DeviceMemoryObject<Device> {
100 type ConcreteDevice = Device;
101
102 #[inline(always)]
103 fn device(&self) -> &Self::ConcreteDevice {
104 &self.1
105 }
106}
107impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceMemory for DeviceMemoryObject<Device> {}
108impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceMemoryMut for DeviceMemoryObject<Device> {}
109impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceMemoryObject<Device> {
110 pub const unsafe fn manage(handle: brvk::VkDeviceMemory, parent: Device) -> Self {
114 Self(handle, parent)
115 }
116
117 pub const fn unmanage(self) -> (brvk::VkDeviceMemory, Device) {
119 let v = self.0;
120 let p = unsafe { core::ptr::read(&self.1) };
121 core::mem::forget(self);
122
123 (v, p)
124 }
125}
126impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> DeviceMemoryObject<&'_ Device> {
127 #[inline(always)]
129 pub fn clone_parent(self) -> DeviceMemoryObject<Device> {
130 let r = DeviceMemoryObject(self.0, self.1.clone());
131 core::mem::forget(self);
132
133 r
134 }
135}
136impl<Device: crate::Device> DeviceMemoryObject<Device> {
137 #[implements]
146 #[inline]
147 pub fn new(device: Device, info: &MemoryAllocateInfo) -> crate::Result<Self> {
148 Ok(unsafe { Self::manage(device.allocate_memory(info, None)?, device) })
149 }
150}
151
152#[repr(transparent)]
154#[derive(Clone)]
155pub struct MemoryAllocateInfo<'d>(
156 brvk::VkMemoryAllocateInfo,
157 core::marker::PhantomData<Option<&'d dyn brvk::VulkanStructure>>,
158);
159impl<'d> MemoryAllocateInfo<'d> {
160 pub const fn new(size: brvk::VkDeviceSize, memory_type_index: u32) -> Self {
161 Self(
162 brvk::VkMemoryAllocateInfo {
163 sType: brvk::VkMemoryAllocateInfo::TYPE,
164 pNext: core::ptr::null(),
165 allocationSize: size,
166 memoryTypeIndex: memory_type_index,
167 },
168 core::marker::PhantomData,
169 )
170 }
171
172 pub const unsafe fn from_raw(raw: brvk::VkMemoryAllocateInfo) -> Self {
176 Self(raw, core::marker::PhantomData)
177 }
178
179 pub const fn into_raw(self) -> brvk::VkMemoryAllocateInfo {
180 self.0
181 }
182
183 pub const fn with_next(mut self, next: &'d (impl brvk::VulkanStructure + ?Sized)) -> Self {
184 self.0.pNext = next as *const _ as _;
185 self
186 }
187
188 pub const unsafe fn next_sink<T: brvk::VulkanStructure>(&mut self) -> &mut *const T {
192 unsafe { core::mem::transmute(&mut self.0.pNext) }
193 }
194}
195unsafe impl brvk::VulkanStructure for MemoryAllocateInfo<'_> {
196 #[inline(always)]
197 fn as_generic(&self) -> &brvk::GenericVulkanStructure {
198 self.0.as_generic()
199 }
200
201 #[inline(always)]
202 fn as_generic_mut(&mut self) -> &mut brvk::GenericVulkanStructure {
203 self.0.as_generic_mut()
204 }
205}
206
207#[cfg(feature = "VK_KHR_dedicated_allocation")]
209#[repr(transparent)]
210#[derive(Clone)]
211pub struct MemoryDedicatedAllocateInfo<'d>(
212 brvk::VkMemoryDedicatedAllocateInfoKHR,
213 #[allow(clippy::type_complexity)]
214 core::marker::PhantomData<(
215 Option<&'d dyn brvk::VulkanStructure>,
216 Option<&'d dyn VkHandle<Handle = brvk::VkImage>>,
217 Option<&'d dyn VkHandle<Handle = brvk::VkBuffer>>,
218 )>,
219);
220#[cfg(feature = "VK_KHR_dedicated_allocation")]
221unsafe impl brvk::VulkanStructure for MemoryDedicatedAllocateInfo<'_> {
222 #[inline(always)]
223 fn as_generic(&self) -> &brvk::GenericVulkanStructure {
224 unsafe { core::mem::transmute(self) }
225 }
226
227 #[inline(always)]
228 fn as_generic_mut(&mut self) -> &mut brvk::GenericVulkanStructure {
229 unsafe { core::mem::transmute(self) }
230 }
231}
232#[cfg(feature = "VK_KHR_dedicated_allocation")]
233impl<'d> MemoryDedicatedAllocateInfo<'d> {
234 #[inline]
235 pub fn for_buffer(buffer: &'d (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized)) -> Self {
236 Self(
237 brvk::VkMemoryDedicatedAllocateInfoKHR {
238 sType: brvk::VkMemoryDedicatedAllocateInfoKHR::TYPE,
239 pNext: core::ptr::null(),
240 image: None,
241 buffer: Some(buffer.native_ptr()),
242 },
243 core::marker::PhantomData,
244 )
245 }
246
247 #[inline]
251 pub const unsafe fn for_buffer_raw(buffer: brvk::VkBuffer) -> Self {
252 Self(
253 brvk::VkMemoryDedicatedAllocateInfoKHR {
254 sType: brvk::VkMemoryDedicatedAllocateInfoKHR::TYPE,
255 pNext: core::ptr::null(),
256 image: None,
257 buffer: Some(buffer),
258 },
259 core::marker::PhantomData,
260 )
261 }
262
263 #[inline]
264 pub fn for_image(image: &'d (impl VkHandle<Handle = brvk::VkImage> + ?Sized)) -> Self {
265 Self(
266 brvk::VkMemoryDedicatedAllocateInfoKHR {
267 sType: brvk::VkMemoryDedicatedAllocateInfoKHR::TYPE,
268 pNext: core::ptr::null(),
269 image: Some(image.native_ptr()),
270 buffer: None,
271 },
272 core::marker::PhantomData,
273 )
274 }
275
276 #[inline]
280 pub const unsafe fn for_image_raw(image: brvk::VkImage) -> Self {
281 Self(
282 brvk::VkMemoryDedicatedAllocateInfoKHR {
283 sType: brvk::VkMemoryDedicatedAllocateInfoKHR::TYPE,
284 pNext: core::ptr::null(),
285 image: Some(image),
286 buffer: None,
287 },
288 core::marker::PhantomData,
289 )
290 }
291
292 pub const unsafe fn from_raw(raw: brvk::VkMemoryDedicatedAllocateInfoKHR) -> Self {
296 Self(raw, core::marker::PhantomData)
297 }
298
299 pub const fn into_raw(self) -> brvk::VkMemoryDedicatedAllocateInfoKHR {
300 self.0
301 }
302
303 pub const fn with_next(mut self, next: &'d (impl brvk::VulkanStructure + ?Sized)) -> Self {
304 self.0.pNext = next as *const _ as _;
305 self
306 }
307
308 pub const unsafe fn next_sink<T: brvk::VulkanStructure>(&mut self) -> &mut *const T {
312 unsafe { core::mem::transmute(&mut self.0.pNext) }
313 }
314}
315
316pub struct MappedMemoryRange<'a>(
318 brvk::VkMappedMemoryRange,
319 core::marker::PhantomData<&'a dyn VkHandle<Handle = brvk::VkDeviceMemory>>,
320);
321impl<'a> MappedMemoryRange<'a> {
322 pub fn new(
323 memory: &'a (impl VkHandle<Handle = brvk::VkDeviceMemory> + ?Sized),
324 range: core::ops::Range<brvk::VkDeviceSize>,
325 ) -> Self {
326 Self(
327 brvk::VkMappedMemoryRange {
328 sType: brvk::VkMappedMemoryRange::TYPE,
329 pNext: core::ptr::null(),
330 memory: memory.native_ptr(),
331 offset: range.start,
332 size: range.end - range.start,
333 },
334 core::marker::PhantomData,
335 )
336 }
337
338 pub const unsafe fn new_raw(
342 memory: brvk::VkDeviceMemory,
343 offset: brvk::VkDeviceSize,
344 size: brvk::VkDeviceSize,
345 ) -> Self {
346 Self(
347 brvk::VkMappedMemoryRange {
348 sType: brvk::VkMappedMemoryRange::TYPE,
349 pNext: core::ptr::null(),
350 memory,
351 offset,
352 size,
353 },
354 core::marker::PhantomData,
355 )
356 }
357
358 pub const unsafe fn from_raw(raw: brvk::VkMappedMemoryRange) -> Self {
362 Self(raw, core::marker::PhantomData)
363 }
364
365 pub const fn into_raw(self) -> brvk::VkMappedMemoryRange {
366 self.0
367 }
368}
369
370pub struct MappedMemory<'m, DeviceMemory: crate::DeviceMemoryMut + ?Sized + 'm>(
372 *mut core::ffi::c_void,
373 &'m mut DeviceMemory,
374);
375#[allow(clippy::mut_from_ref)]
376impl<'m, DeviceMemory: crate::DeviceMemoryMut + ?Sized + 'm> MappedMemory<'m, DeviceMemory> {
377 pub const fn ptr(&self) -> *mut core::ffi::c_void {
379 self.0
380 }
381
382 pub const unsafe fn addr_of_mut<T>(&self, offset: usize) -> *mut T {
386 unsafe { self.0.byte_add(offset) as *mut T }
387 }
388
389 pub const unsafe fn get<T>(&self, offset: usize) -> &T {
393 unsafe { &*(self.0.byte_add(offset) as *const T) }
394 }
395
396 pub const unsafe fn get_mut<T>(&self, offset: usize) -> &mut T {
400 unsafe { &mut *(self.0.byte_add(offset) as *mut T) }
401 }
402
403 pub const unsafe fn slice<T>(&self, offset: usize, count: usize) -> &[T] {
407 unsafe { core::slice::from_raw_parts(self.0.byte_add(offset) as *const T, count) }
408 }
409
410 pub const unsafe fn slice_mut<T>(&self, offset: usize, count: usize) -> &mut [T] {
414 unsafe { core::slice::from_raw_parts_mut(self.0.byte_add(offset) as *mut T, count) }
415 }
416
417 #[inline(always)]
421 pub unsafe fn clone_from_slice_at<T: Clone>(&self, offset: usize, src: &[T]) {
422 unsafe { self.slice_mut(offset, src.len()).clone_from_slice(src) };
423 }
424
425 #[inline(always)]
429 pub unsafe fn clone_at<T: Clone>(&self, offset: usize, src: &T) {
430 unsafe { *self.get_mut(offset) = src.clone() };
431 }
432
433 #[implements]
434 pub fn end(self) {
436 unsafe {
437 self.1.unmap();
438 }
439 }
440}