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
9pub 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 #[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#[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 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}