ggez/graphics/gpu/
growing.rs1use super::arc::ArcBuffer;
2
3#[derive(Debug)]
10pub struct GrowingBufferArena {
11 buffers: Vec<(ArcBuffer, u64)>,
12 alignment: u64,
13 desc: wgpu::BufferDescriptor<'static>,
14}
15
16impl GrowingBufferArena {
17 pub fn new(
18 device: &wgpu::Device,
19 alignment: u64,
20 desc: wgpu::BufferDescriptor<'static>,
21 ) -> Self {
22 GrowingBufferArena {
23 buffers: vec![(ArcBuffer::new(device.create_buffer(&desc)), 0)],
24 alignment,
25 desc,
26 }
27 }
28
29 pub fn allocate(&mut self, device: &wgpu::Device, size: u64) -> ArenaAllocation {
30 let size = align(self.alignment, size);
31 assert!(size <= self.desc.size);
32
33 for (buffer, cursor) in &mut self.buffers {
34 if size <= self.desc.size - *cursor {
35 let offset = *cursor;
36 *cursor += size;
37 return ArenaAllocation {
38 buffer: buffer.clone(),
39 offset,
40 };
41 }
42 }
43
44 self.grow(device);
45 self.allocate(device, size)
46 }
47
48 pub fn free(&mut self) {
50 for (_, cursor) in &mut self.buffers {
51 *cursor = 0;
52 }
53 }
54
55 fn grow(&mut self, device: &wgpu::Device) {
56 self.buffers
57 .push((ArcBuffer::new(device.create_buffer(&self.desc)), 0));
58 }
59}
60
61#[derive(Debug, Clone)]
62pub struct ArenaAllocation {
63 pub buffer: ArcBuffer,
64 pub offset: u64,
65}
66
67fn align(alignment: u64, size: u64) -> u64 {
68 (size + alignment - 1) & !(alignment - 1)
69}