1    private@
2    
3    type Version = struct
4        framebuffer : VkFramebuffer
5        render_pass : RenderPass
6    
7    public@
8    
9    type FramebufferOps = struct
10       color_enter_op : EnterOp
11       color_exit_op : ExitOp
12       depth_enter_op : EnterOp
13       depth_exit_op : ExitOp
14   
15   type Framebuffer =
16       let vulkan : Vulkan
17       val format : RenderPassFormat
18       val images : List<Image>
19       var size : Size @mut
20       let versions : mut Map<FramebufferOps, Version>
21   
22       let reset () =
23           vk/device_wait_idle vulkan.instance.device
24           for _, v in versions do
25               vk/destroy_framebuffer vulkan.instance.device v.framebuffer null
26   
27           versions.clear
28   
29       observe@ size { reset }
30   
31       def get (color_enter_op : EnterOp
32                color_exit_op : ExitOp
33                depth_enter_op : EnterOp
34                depth_exit_op : ExitOp) : (VkFramebuffer, RenderPass) =
35           let ops = FramebufferOps =color_enter_op =color_exit_op =depth_enter_op
36                                    =depth_exit_op
37   
38           if not versions.contains ops then
39               let settings = Settings =color_enter_op =color_exit_op
40                                       =depth_enter_op =depth_exit_op
41                                       no_dependencies = false
42   
43               let render_pass = RenderPass.create format settings
44                                                   vulkan.render_pass_cache
45   
46               let mut version = Version framebuffer = null
47                                         =render_pass
48   
49               let attachments = images.map { _.view }
50               for image in images do
51                   assert image.width >= size.width && image.height >= size.height
52   
53               let framebuffer_create_info = FramebufferCreateInfo
54                   type = StructureType/FramebufferCreateInfo
55                   next = null
56                   flags = FramebufferCreateFlags@zero
57                   render_pass = render_pass.object
58                   attachment_count = attachments.size
59                   attachments = attachments.as_ptr
60                   width = size.width
61                   height = size.height
62                   layers = 1
63   
64               vk/create_framebuffer vulkan.instance.device
65                                     framebuffer_create_info@ptr
66                                     null version.framebuffer@mut_ptr
67               |> assert_success
68   
69               versions.add ops version
70   
71           let version = versions[ops]
72   
73           (version.framebuffer, version.render_pass)
74   
75   object Framebuffer =
76       def create (size : Size) (images : List<Image>) =
77           let vulkan : Vulkan @auto
78   
79           for image in images do
80               assert image.array_layers == 1 && image.width >= size.width
81                      && image.height >= size.height
82   
83           let attachments = images.map { image -> AttachmentFormat
84               format = image.format
85               samples = image.samples
86               usage = image.usage }
87   
88           let format = RenderPassFormat.create attachments
89   
90           Framebuffer =vulkan =format =images =size
91                       versions = Map.new
92