1    begin@ write
2    
3    private@
4    
5    type Block @[mut local] =
6        val buffer : VkBuffer
7        val memory : VkMemory
8        val size : u32
9        var frame_used : u32 = 0
10       var position : u32 = 0
11   
12       def aligned (alignment : u32) =
13           let remainder = position % alignment
14           if remainder == 0
15           then position
16           else position - remainder + alignment
17   
18       def remaining (alignment : u32) =
19           let x = aligned alignment
20           if size > x
21           then size - x
22           else 0
23   
24   public@
25   
26   type BufferPool =
27       let instance : Instance @auto
28   
29       var frame_index : u32
30       val frame_offset : u32
31       val block_size : u32
32       var block_index : u32 = 0
33       let blocks = List<Block>.new
34   
35       def next_frame =
36           frame_index += 1
37   
38       def current = blocks[block_index]
39       local is_current_unused () = current.frame_used <= frame_index - frame_offset
40   
41       local skip_block () =
42           block_index = (block_index + 1) % blocks.size
43   
44       local add_block () =
45           let flags = MemoryPropertyFlags/HostVisible
46                       | MemoryPropertyFlags/HostCoherent
47   
48           let (buffer, memory) =
49               vulkan/buffer/create instance.physical_device instance.device
50                                    block_size.as<u64> BufferUsageFlags/TransferSrc
51                                    flags
52   
53           let block = Block buffer memory block_size
54           blocks.add block_index block
55   
56   object BufferPool =
57       def create (frame_count : u32) =
58           let pool = BufferPool frame_index = frame_count
59                                 frame_offset = frame_count
60                                 block_size = 512 * 512 * 16
61   
62           for i = 0 until frame_count do
63               pool.add_block
64   
65           pool
66