bort_vk/
buffer.rs

1use crate::{AllocationAccess, AllocatorAccess, Device, DeviceOwned, MemoryAllocation};
2use ash::{
3    prelude::VkResult,
4    vk::{self, Handle},
5};
6use bort_vma::{Alloc, AllocationCreateInfo};
7use std::sync::Arc;
8
9/// Contains a [VkBuffer](https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkBuffer.html)
10/// and a memory allocation.
11pub struct Buffer {
12    handle: vk::Buffer,
13    properties: BufferProperties,
14    memory_allocation: MemoryAllocation,
15}
16
17impl Buffer {
18    pub fn new(
19        alloc_access: Arc<dyn AllocatorAccess>,
20        buffer_properties: BufferProperties,
21        allocation_info: AllocationCreateInfo,
22    ) -> VkResult<Self> {
23        let create_info_builder = buffer_properties.create_info_builder();
24
25        let (handle, vma_allocation) = unsafe {
26            alloc_access
27                .vma_allocator()
28                .create_buffer(&create_info_builder, &allocation_info)
29        }?;
30
31        Ok(Self::from_handle_and_allocation(
32            alloc_access,
33            buffer_properties,
34            handle,
35            vma_allocation,
36        ))
37    }
38
39    pub unsafe fn new_from_create_info(
40        alloc_access: Arc<dyn AllocatorAccess>,
41        buffer_create_info_builder: vk::BufferCreateInfoBuilder,
42        allocation_info: AllocationCreateInfo,
43    ) -> VkResult<Self> {
44        let properties = BufferProperties::from_create_info_builder(&buffer_create_info_builder);
45
46        let (handle, vma_allocation) = unsafe {
47            alloc_access
48                .vma_allocator()
49                .create_buffer(&buffer_create_info_builder, &allocation_info)
50        }?;
51
52        Ok(Self::from_handle_and_allocation(
53            alloc_access,
54            properties,
55            handle,
56            vma_allocation,
57        ))
58    }
59
60    fn from_handle_and_allocation(
61        alloc_access: Arc<dyn AllocatorAccess>,
62        properties: BufferProperties,
63        handle: vk::Buffer,
64        vma_allocation: bort_vma::Allocation,
65    ) -> Self {
66        let memory_allocation = MemoryAllocation::from_vma_allocation(vma_allocation, alloc_access);
67
68        Self {
69            handle,
70            properties,
71            memory_allocation,
72        }
73    }
74
75    // Getters
76
77    #[inline]
78    pub fn handle(&self) -> vk::Buffer {
79        self.handle
80    }
81
82    #[inline]
83    pub fn properties(&self) -> &BufferProperties {
84        &self.properties
85    }
86
87    #[inline]
88    pub fn allocator_access(&self) -> &Arc<dyn AllocatorAccess> {
89        &self.memory_allocation.allocator_access()
90    }
91
92    #[inline]
93    pub fn memory_allocation(&self) -> &MemoryAllocation {
94        &self.memory_allocation
95    }
96}
97
98impl AllocationAccess for Buffer {
99    fn memory_allocation_mut(&mut self) -> &mut MemoryAllocation {
100        &mut self.memory_allocation
101    }
102}
103
104impl DeviceOwned for Buffer {
105    #[inline]
106    fn device(&self) -> &Arc<Device> {
107        &self.allocator_access().device()
108    }
109
110    #[inline]
111    fn handle_raw(&self) -> u64 {
112        self.handle.as_raw()
113    }
114}
115
116impl Drop for Buffer {
117    fn drop(&mut self) {
118        unsafe {
119            self.allocator_access()
120                .clone()
121                .vma_allocator()
122                .destroy_buffer(self.handle, self.memory_allocation.inner_mut());
123        }
124    }
125}
126
127// Properties
128
129/// Note: default values for `size`, and `usage` are nothing!
130#[derive(Clone)]
131pub struct BufferProperties {
132    pub flags: vk::BufferCreateFlags,
133    pub size: vk::DeviceSize,
134    pub usage: vk::BufferUsageFlags,
135    pub sharing_mode: vk::SharingMode,
136    pub queue_family_indices: Vec<u32>,
137}
138
139impl Default for BufferProperties {
140    fn default() -> Self {
141        Self {
142            flags: vk::BufferCreateFlags::empty(),
143            sharing_mode: vk::SharingMode::EXCLUSIVE,
144            queue_family_indices: Vec::new(),
145
146            // nonsense defaults. make sure you override these!
147            size: 0,
148            usage: vk::BufferUsageFlags::empty(),
149        }
150    }
151}
152
153impl BufferProperties {
154    pub fn new_default(size: vk::DeviceSize, usage: vk::BufferUsageFlags) -> Self {
155        Self {
156            size,
157            usage,
158            ..Default::default()
159        }
160    }
161
162    pub fn write_create_info_builder<'a>(
163        &'a self,
164        builder: vk::BufferCreateInfoBuilder<'a>,
165    ) -> vk::BufferCreateInfoBuilder<'a> {
166        builder
167            .flags(self.flags)
168            .size(self.size)
169            .usage(self.usage)
170            .sharing_mode(self.sharing_mode)
171            .queue_family_indices(&self.queue_family_indices)
172    }
173
174    pub fn create_info_builder(&self) -> vk::BufferCreateInfoBuilder {
175        self.write_create_info_builder(vk::BufferCreateInfo::builder())
176    }
177
178    pub fn from_create_info_builder(value: &vk::BufferCreateInfoBuilder) -> Self {
179        let mut queue_family_indices = Vec::<u32>::new();
180        for i in 0..value.queue_family_index_count {
181            let queue_family_index = unsafe { *value.p_queue_family_indices.offset(i as isize) };
182            queue_family_indices.push(queue_family_index);
183        }
184
185        Self {
186            flags: value.flags,
187            size: value.size,
188            usage: value.usage,
189            sharing_mode: value.sharing_mode,
190            queue_family_indices: queue_family_indices,
191        }
192    }
193}