1     let frame_lag = 2
2     
3     type Sync =
4         let image_count : u32
5         var semaphore_acquired @mut = false
6         var fences = [VkFence; frame_lag]@zero
7         var image_acquired_semaphores = [VkSemaphore; frame_lag]@zero
8         var ready_for_present_semaphores = Array<VkSemaphore> image_count
9         var sync_index : u32 = 0
10    
11        def next_frame =
12            sync_index = (sync_index + 1) % frame_lag
13    
14        fun destruct =
15            ready_for_present_semaphores.discard
16    
17    def create_fence =
18        let instance : Instance @auto
19        let fence_create_info = FenceCreateInfo
20            type = StructureType/FenceCreateInfo
21            next = null
22            flags = FenceCreateFlags/Signaled
23    
24        let mut fence = null
25        vk/create_fence instance.device fence_create_info@ptr null fence@mut_ptr
26        |> assert_success
27    
28        fence
29    
30    def create_semaphore =
31        let instance : Instance @auto
32        let semaphore_create_info = SemaphoreCreateInfo
33            type = StructureType/SemaphoreCreateInfo
34            next = null
35            flags = SemaphoreCreateFlags@zero
36    
37        let mut semaphore = null
38        vk/create_semaphore instance.device semaphore_create_info@ptr
39                            null semaphore@mut_ptr
40        |> assert_success
41    
42        semaphore
43    
44    object Sync =
45        def create (image_count : u32) =
46            let sync = Sync image_count
47            for i = 0 until frame_lag do
48                sync.fences[i] = create_fence
49                sync.image_acquired_semaphores[i] = create_semaphore
50    
51            for i = 0 until image_count do
52                sync.ready_for_present_semaphores[i] = create_semaphore
53    
54            sync
55    
56    def barrier (command_buffer : VkCommandBuffer
57                 from : BarrierFlags
58                 to : BarrierFlags) =
59        let mut src_stage_flags = PipelineStageFlags@zero
60        let mut src_access_flags = AccessFlags@zero
61    
62        if from.contains BarrierFlags/Compute then
63            src_stage_flags |= PipelineStageFlags/ComputeShader
64            src_access_flags |= AccessFlags/ShaderWrite
65    
66        if from.contains BarrierFlags/Raster then
67            src_stage_flags |= PipelineStageFlags/ColorAttachmentOutput
68                               | PipelineStageFlags/LateFragmentTests
69            src_access_flags |= AccessFlags/DepthStencilAttachmentWrite
70                                | AccessFlags/ColorAttachmentWrite
71    
72        if from.contains BarrierFlags/Transfer then
73            src_stage_flags |= PipelineStageFlags/Transfer
74            src_access_flags |= AccessFlags/TransferWrite
75    
76        if from == BarrierFlags@zero then
77            src_stage_flags = PipelineStageFlags/TopOfPipe
78    
79        let mut dst_stage_flags = PipelineStageFlags@zero
80        let mut dst_access_flags = AccessFlags@zero
81    
82        if to.contains BarrierFlags/Compute then
83            dst_stage_flags |= PipelineStageFlags/ComputeShader
84            dst_access_flags |= AccessFlags/ShaderRead | AccessFlags/ShaderWrite
85    
86        if to.contains BarrierFlags/Raster then
87            dst_stage_flags |= PipelineStageFlags/VertexInput
88                               | PipelineStageFlags/VertexShader
89                               | PipelineStageFlags/FragmentShader
90                               | PipelineStageFlags/DrawIndirect
91            dst_access_flags |= AccessFlags/ShaderRead
92                                | AccessFlags/ShaderWrite
93                                | AccessFlags/IndexRead
94                                | AccessFlags/VertexAttributeRead
95                                | AccessFlags/IndirectCommandRead
96    
97        if to.contains BarrierFlags/Transfer then
98            dst_stage_flags |= PipelineStageFlags/Transfer
99            dst_access_flags |= AccessFlags/TransferRead | AccessFlags/TransferWrite
100   
101       if to == BarrierFlags@zero then
102           dst_stage_flags = PipelineStageFlags/BottomOfPipe
103   
104       let memory_barrier = MemoryBarrier
105           type = StructureType/MemoryBarrier
106           next = null
107           src_access_mask = src_access_flags
108           dst_access_mask = dst_access_flags
109   
110       assert src_stage_flags <> PipelineStageFlags@zero
111              && dst_stage_flags <> PipelineStageFlags@zero
112   
113       vk/cmd_pipeline_barrier command_buffer src_stage_flags dst_stage_flags
114                               DependencyFlags@zero 1 memory_barrier@ptr
115                               0 null 0 null
116