1use super::*;
2
3#[derive(Clone, Copy, Debug)]
4pub struct BufferCreator(vk::BufferCreateInfo);
5
6impl BufferCreator {
7 #[must_use]
8 pub fn new(size: vk::DeviceSize, usage: impl Into<vk::BufferUsageFlags> + Copy) -> Self {
9 Self(vk::BufferCreateInfo {
10 s_type: vk::StructureType::BufferCreateInfo,
11 p_next: null(),
12 flags: vk::BufferCreateFlags::empty(),
13 size,
14 usage: usage.into() | vk::BufferUsageFlagBits::ShaderDeviceAddress,
15 sharing_mode: vk::SharingMode::Exclusive,
16 queue_family_index_count: 0,
17 p_queue_family_indices: null(),
18 })
19 }
20
21 pub unsafe fn create(self, device: &Device) -> Result<(vk::Buffer, vk::BufferCreateInfo)> {
22 let buffer_create_info = self.0;
23 let buffer = device.create_buffer(&buffer_create_info)?;
24 Ok((buffer, buffer_create_info))
25 }
26}
27
28pub trait BufferOps {
29 fn buffer_handle(&self) -> vk::Buffer;
30
31 fn create_info(&self) -> &vk::BufferCreateInfo;
32
33 fn memory(&self) -> &BufferAllocation;
34
35 fn memory_mut(&mut self) -> &mut BufferAllocation;
36
37 fn size(&self) -> vk::DeviceSize {
38 self.create_info().size
39 }
40}
41
42pub trait BufferResourceOps {
43 fn descriptor(&self) -> Descriptor;
44}
45
46#[derive(Debug)]
48pub struct BufferResource {
49 buffer: vk::Buffer,
50 buffer_create_info: vk::BufferCreateInfo,
51 buffer_allocation: BufferAllocation,
52 descriptor: Descriptor,
53}
54
55impl BufferResource {
56 pub unsafe fn create(
57 physical_device: &PhysicalDevice,
58 device: &Device,
59 buffer_creators: &[BufferCreator],
60 property_flags: impl Into<vk::MemoryPropertyFlags> + Copy,
61 ) -> Result<(Vec<Self>, BufferAllocations)> {
62 const UNIFORM_BUFFER: vk::BufferUsageFlagBits = vk::BufferUsageFlagBits::UniformBuffer;
64 const STORAGE_BUFFER: vk::BufferUsageFlagBits = vk::BufferUsageFlagBits::StorageBuffer;
65 const AS_BUFFER: vk::BufferUsageFlagBits =
66 vk::BufferUsageFlagBits::AccelerationStructureStorageKHR;
67
68 let mut buffers = Vec::with_capacity(buffer_creators.len());
70 let mut buffer_create_infos = Vec::with_capacity(buffer_creators.len());
71 for &buffer_creator in buffer_creators {
72 let (buffer, buffer_create_info) = buffer_creator.create(device)?;
73 buffers.push(buffer);
74 buffer_create_infos.push(buffer_create_info);
75 }
76
77 let buffer_allocations = BufferAllocations::allocate(
79 physical_device,
80 device,
81 &buffers,
82 &buffer_create_infos,
83 property_flags,
84 )?;
85
86 let mut descriptors = Vec::with_capacity(buffer_creators.len());
88 for (buffer_allocation, buffer_create_info) in buffer_allocations
89 .allocations()
90 .iter()
91 .zip(&buffer_create_infos)
92 {
93 let usage = buffer_create_info.usage;
94 let descriptor = if usage.contains(UNIFORM_BUFFER) {
95 Descriptor::create(
97 physical_device,
98 device,
99 DescriptorCreateInfo::UniformBuffer {
100 address: buffer_allocation.device_address(),
101 range: buffer_create_info.size,
102 },
103 )
104 } else if usage.contains(STORAGE_BUFFER) {
105 Descriptor::create(
106 physical_device,
107 device,
108 DescriptorCreateInfo::StorageBuffer {
109 address: buffer_allocation.device_address(),
110 range: buffer_create_info.size,
111 },
112 )
113 } else if usage.contains(AS_BUFFER) {
114 Descriptor::create(
115 physical_device,
116 device,
117 DescriptorCreateInfo::AccelerationStructure(buffer_allocation.device_address()),
118 )
119 } else {
120 bail!(
121 "Buffer resource must be \
122 {UNIFORM_BUFFER} or \
123 {STORAGE_BUFFER} or \
124 {AS_BUFFER}, \
125 got {usage}"
126 );
127 };
128 descriptors.push(descriptor);
129 }
130
131 let mut buffer_resources = Vec::with_capacity(buffer_creators.len());
133 for i in 0..buffer_creators.len() {
134 let buffer = buffers[i];
135 let buffer_create_info = buffer_create_infos[i];
136 let buffer_allocation = buffer_allocations.allocations()[i];
137 let descriptor = descriptors[i];
138 buffer_resources.push(Self {
139 buffer,
140 buffer_create_info,
141 buffer_allocation,
142 descriptor,
143 });
144 }
145 Ok((buffer_resources, buffer_allocations))
146 }
147
148 pub unsafe fn destroy(self, device: &Device) {
149 device.destroy_buffer(self.buffer);
150 }
151}
152
153impl BufferOps for BufferResource {
154 fn buffer_handle(&self) -> vk::Buffer {
155 self.buffer
156 }
157
158 fn create_info(&self) -> &vk::BufferCreateInfo {
159 &self.buffer_create_info
160 }
161
162 fn memory(&self) -> &BufferAllocation {
163 &self.buffer_allocation
164 }
165
166 fn memory_mut(&mut self) -> &mut BufferAllocation {
167 &mut self.buffer_allocation
168 }
169}
170
171impl BufferResourceOps for BufferResource {
172 fn descriptor(&self) -> Descriptor {
173 self.descriptor
174 }
175}
176
177#[derive(Debug)]
179pub struct BufferDedicatedResource {
180 buffer_resource: BufferResource,
181 buffer_allocations: BufferAllocations,
182}
183
184impl BufferDedicatedResource {
185 pub unsafe fn create(
186 physical_device: &PhysicalDevice,
187 device: &Device,
188 buffer_creator: BufferCreator,
189 property_flags: impl Into<vk::MemoryPropertyFlags> + Copy,
190 ) -> Result<Self> {
191 let (mut buffer_resources, buffer_allocations) =
192 BufferResource::create(physical_device, device, &[buffer_creator], property_flags)?;
193 let buffer_resource = buffer_resources.swap_remove(0);
194 Ok(Self {
195 buffer_resource,
196 buffer_allocations,
197 })
198 }
199
200 pub unsafe fn destroy(self, device: &Device) {
201 self.buffer_resource.destroy(device);
202 self.buffer_allocations.free(device);
203 }
204}
205
206impl BufferOps for BufferDedicatedResource {
207 fn buffer_handle(&self) -> vk::Buffer {
208 self.buffer_resource.buffer
209 }
210
211 fn create_info(&self) -> &vk::BufferCreateInfo {
212 &self.buffer_resource.buffer_create_info
213 }
214
215 fn memory(&self) -> &BufferAllocation {
216 &self.buffer_resource.buffer_allocation
217 }
218
219 fn memory_mut(&mut self) -> &mut BufferAllocation {
220 &mut self.buffer_resource.buffer_allocation
221 }
222}
223
224impl BufferResourceOps for BufferDedicatedResource {
225 fn descriptor(&self) -> Descriptor {
226 self.buffer_resource.descriptor
227 }
228}
229
230#[derive(Debug)]
233pub struct BufferDedicatedTransfer {
234 buffer: vk::Buffer,
235 buffer_create_info: vk::BufferCreateInfo,
236 buffer_allocations: BufferAllocations,
237 buffer_allocation: BufferAllocation,
238}
239
240impl BufferDedicatedTransfer {
241 pub unsafe fn create(
242 physical_device: &PhysicalDevice,
243 device: &Device,
244 buffer_creator: BufferCreator,
245 property_flags: impl Into<vk::MemoryPropertyFlags> + Copy,
246 ) -> Result<Self> {
247 const TRANSFER_SRC: vk::BufferUsageFlagBits = vk::BufferUsageFlagBits::TransferSrc;
249 const TRANSFER_DST: vk::BufferUsageFlagBits = vk::BufferUsageFlagBits::TransferDst;
250 const AS_BUILD_ONLY: vk::BufferUsageFlagBits =
251 vk::BufferUsageFlagBits::AccelerationStructureBuildInputReadOnlyKHR;
252
253 ensure!(buffer_creator.0.size > 0);
254 ensure!(
255 buffer_creator.0.usage.contains(TRANSFER_SRC)
256 || buffer_creator.0.usage.contains(TRANSFER_DST)
257 || buffer_creator.0.usage.contains(AS_BUILD_ONLY),
258 "got {}",
259 buffer_creator.0.usage
260 );
261 ensure!(property_flags
262 .into()
263 .contains(vk::MemoryPropertyFlagBits::HostVisible));
264
265 let (buffer, buffer_create_info) = buffer_creator.create(device)?;
267
268 let buffer_allocations = BufferAllocations::allocate(
270 physical_device,
271 device,
272 &[buffer],
273 &[buffer_create_info],
274 property_flags,
275 )?;
276 let buffer_allocation = buffer_allocations.allocations()[0];
277
278 Ok(Self {
279 buffer,
280 buffer_create_info,
281 buffer_allocations,
282 buffer_allocation,
283 })
284 }
285
286 pub unsafe fn destroy(self, device: &Device) {
287 device.destroy_buffer(self.buffer);
288 self.buffer_allocations.free(device);
289 }
290}
291
292impl BufferOps for BufferDedicatedTransfer {
293 fn buffer_handle(&self) -> vk::Buffer {
294 self.buffer
295 }
296
297 fn create_info(&self) -> &vk::BufferCreateInfo {
298 &self.buffer_create_info
299 }
300
301 fn memory(&self) -> &BufferAllocation {
302 &self.buffer_allocation
303 }
304
305 fn memory_mut(&mut self) -> &mut BufferAllocation {
306 &mut self.buffer_allocation
307 }
308}
309
310#[derive(Debug)]
312pub struct BufferShaderBindingTable {
313 buffer: vk::Buffer,
314 buffer_create_info: vk::BufferCreateInfo,
315 buffer_allocation: BufferAllocation,
316}
317
318impl BufferShaderBindingTable {
319 pub unsafe fn create(
320 buffers: &[vk::Buffer],
321 buffer_create_infos: &[vk::BufferCreateInfo],
322 buffer_allocations: &[BufferAllocation],
323 ) -> Result<Vec<Self>> {
324 ensure!(!buffers.is_empty());
326 ensure!(buffers.len() == buffer_create_infos.len());
327 ensure!(buffers.len() == buffer_allocations.len());
328
329 let mut buffer_sbts = vec![];
331 for i in 0..buffers.len() {
332 let buffer = buffers[i];
333 let buffer_create_info = buffer_create_infos[i];
334 let buffer_allocation = buffer_allocations[i];
335 buffer_sbts.push(Self {
336 buffer,
337 buffer_create_info,
338 buffer_allocation,
339 });
340 }
341 Ok(buffer_sbts)
342 }
343
344 pub unsafe fn destroy(self, device: &Device) {
345 device.destroy_buffer(self.buffer);
346 }
347}
348
349impl BufferOps for BufferShaderBindingTable {
350 fn buffer_handle(&self) -> vk::Buffer {
351 self.buffer
352 }
353
354 fn create_info(&self) -> &vk::BufferCreateInfo {
355 &self.buffer_create_info
356 }
357
358 fn memory(&self) -> &BufferAllocation {
359 &self.buffer_allocation
360 }
361
362 fn memory_mut(&mut self) -> &mut BufferAllocation {
363 &mut self.buffer_allocation
364 }
365}