1    type Target =
2        | Buffer VkBuffer
3        | Image image : VkImage
4                width : u32
5                height : u32
6    
7    module buffer
8    
9    def write (target : Target
10              data : Ptr
11              size : u32
12              alignment : u32) =
13       let instance : Instance @auto
14       let command_buffer : CommandBuffer @auto
15       let buffer_pool : BufferPool @auto
16   
17       let can_use_current () =
18           buffer_pool.is_current_unused
19           || buffer_pool.current.remaining alignment >= size
20   
21       if not can_use_current then
22           buffer_pool.skip_block
23   
24       if buffer_pool.is_current_unused then
25           buffer_pool.current.position = 0
26   
27       if not can_use_current then
28           buffer_pool.add_block
29   
30       let block = buffer_pool.current
31       block.frame_used = buffer_pool.frame_index
32       let offset = block.aligned alignment
33   
34       let mut ptr = null
35       vk/map_memory instance.device block.memory 0 block.size.as<u64>
36                     MemoryMapFlags@zero ptr@mut_ptr
37       |> assert_success
38   
39       cstd/memcpy (ptr + offset) data size.as<usize>
40       vk/unmap_memory instance.device block.memory
41   
42       case target of
43           Target/Buffer buffer ->
44               let region = BufferCopy src_offset = offset as u64
45                                       dst_offset = 0
46                                       size = size as u64
47   
48               vk/cmd_copy_buffer command_buffer.object block.buffer buffer 1
49                                  region@ptr
50   
51           is Target/Image ->
52               let region = BufferImageCopy
53                   buffer_offset = offset as u64
54                   buffer_row_length = 0
55                   buffer_image_height = 0
56                   image_subresource = ImageSubresourceLayers
57                       aspect_mask = ImageAspectFlags/Color
58                       mip_level = 0
59                       base_array_layer = 0
60                       layer_count = 1
61   
62                   image_offset = Offset3D x = 0
63                                           y = 0
64                                           z = 0
65   
66                   image_extent = Extent3D width = target.width
67                                           height = target.height
68                                           depth = 1
69   
70               vk/cmd_copy_buffer_to_image command_buffer.object block.buffer
71                                           target.image ImageLayout/TransferDstOptimal
72                                           1 region@ptr
73   
74       block.position = offset + size
75   
76   end@ write
77