1     def create_depth (width : u32
2                       height : u32
3                       is_msaa : bool) =
4         let (format, aspect_flags, usage) = if not is_msaa then
5             (VkFormat/D24_UNORM_S8_UINT
6              ImageAspectFlags/Depth
7              ImageUsageFlags/DepthStencilAttachment | ImageUsageFlags/Sampled)
8         else
9             let usage = ImageUsageFlags/TransferDst
10                        | ImageUsageFlags/Storage
11                        | ImageUsageFlags/Sampled
12    
13            (VkFormat/R32_SFLOAT
14             ImageAspectFlags/Color
15             usage)
16    
17        let depth_properties = ImageProperties
18            =width
19            =height
20            =format
21            =aspect_flags
22            =usage
23            f@ ImageProperties.default
24    
25        let depth = Image.create "depth" depth_properties@ref
26        depth.transition ImageLayout/Undefined ImageLayout/ShaderReadOnlyOptimal
27        depth
28    
29    let create_color (width : u32
30                      height : u32
31                      is_msaa : bool) =
32        let color_properties = ImageProperties
33            format = VkFormat/R16G16B16A16_SFLOAT
34            =width
35            =height
36            array_layers = 1
37            usage = ImageUsageFlags/Sampled
38                    | ImageUsageFlags/Storage
39                    | if is_msaa
40                      then ImageUsageFlags/TransferDst | ImageUsageFlags/Storage
41                      else ImageUsageFlags/ColorAttachment
42    
43            f@ ImageProperties.default
44    
45        let color = Image.create "color" color_properties@ref
46        color.transition ImageLayout/Undefined ImageLayout/ShaderReadOnlyOptimal
47        color
48    
49    def create_for_render (size : Atom<Size>
50                           max_size : Size
51                           samples : SampleCountFlags) : (Token, Image, List<Node>) =
52        let vulkan : Vulkan @auto
53    
54        let width = max_size.width
55        let height = max_size.height
56        let is_msaa = samples <> SampleCountFlags/1
57        let color = create_color width height is_msaa
58        let depth = create_depth width height is_msaa
59    
60        let sampler =
61            let properties = SamplerProperties
62                mag_filter = VkFilter/Linear
63                min_filter = VkFilter/Linear
64                max_lod = 0
65                f@ SamplerProperties.default
66    
67            VkSampler.create vulkan.instance.device properties@ref
68    
69        let color_msaa : Image @late
70        let depth_msaa : Image @late
71        let color_framebuffer : Framebuffer @late
72        let depth_framebuffer : Framebuffer @late
73        let resolve_depth_source_descriptor_set : DescriptorSet @late
74        let resolve_depth_destination_descriptor_set : DescriptorSet @late
75        if not is_msaa then
76            color_msaa = null
77            color_framebuffer = Framebuffer.create size.value [color, depth]
78            depth_framebuffer = Framebuffer.create size.value [depth]
79            resolve_depth_source_descriptor_set = null
80            resolve_depth_destination_descriptor_set = null
81        else
82            let color_properties = ImageProperties
83                format = VkFormat/R16G16B16A16_SFLOAT
84                width = width as u32
85                height = height as u32
86                view_type = ViewType/2d
87                usage = ImageUsageFlags/ColorAttachment
88                        | ImageUsageFlags/TransferSrc
89                        | ImageUsageFlags/Sampled
90    
91                =samples
92                f@ ImageProperties.default
93    
94            color_msaa = Image.create "color msaa" color_properties@ref
95            color_msaa.transition ImageLayout/Undefined
96                                  ImageLayout/ShaderReadOnlyOptimal
97    
98            let depth_properties = ImageProperties
99                format = VkFormat/D24_UNORM_S8_UINT
100               aspect_flags = ImageAspectFlags/Depth
101               usage = ImageUsageFlags/DepthStencilAttachment
102                       | ImageUsageFlags/TransferSrc
103                       | ImageUsageFlags/Sampled
104   
105               f@ color_properties
106   
107           depth_msaa = Image.create "depth msaa" depth_properties@ref
108           depth_msaa.transition ImageLayout/Undefined
109                                 ImageLayout/ShaderReadOnlyOptimal
110   
111           color_framebuffer = Framebuffer.create size.value
112                                                  [color_msaa, depth_msaa]
113           depth_framebuffer = Framebuffer.create size.value [depth_msaa]
114   
115           resolve_depth_source_descriptor_set = DescriptorSet.create
116               [(depth_msaa, sampler).to_descriptor "source"]
117               vulkan.resolve.pipeline_layout[0]
118   
119           resolve_depth_destination_descriptor_set = DescriptorSet.create
120               [depth.to_descriptor "destination"]
121               vulkan.resolve.pipeline_layout[1]
122   
123       let (tonemap_framebuffer, tonemap_color) =
124           let tonemap_depth =
125               let properties = ImageProperties
126                   =width
127                   =height
128                   format = VkFormat/D24_UNORM_S8_UINT
129                   aspect_flags = ImageAspectFlags/Depth | ImageAspectFlags/Stencil
130                   usage = ImageUsageFlags/DepthStencilAttachment
131                   f@ ImageProperties.default
132   
133               Image.create "tonemap depth" properties@ref
134   
135           tonemap_depth.transition ImageLayout/Undefined
136                                    ImageLayout/DepthStencilAttachmentOptimal
137   
138           let tonemap_color =
139               let properties = ImageProperties
140                   =width
141                   =height
142                   format = VkFormat/R8G8B8A8_UNORM
143                   usage = ImageUsageFlags/ColorAttachment | ImageUsageFlags/Sampled
144                   f@ ImageProperties.default
145   
146               Image.create "tonemap color" properties@ref
147   
148           tonemap_color.transition ImageLayout/Undefined
149                                    ImageLayout/ShaderReadOnlyOptimal
150   
151           let tonemap_framebuffer =
152               Framebuffer.create size.value [tonemap_depth, tonemap_color]
153   
154           (tonemap_framebuffer, tonemap_color)
155   
156       let tonemap_descriptor_set = DescriptorSet.create
157           [(color, sampler).to_descriptor "source_color"]
158           vulkan.tonemap.pipeline_layout[0]
159   
160       let depth_pre_pass = Node/Render
161           ops = FramebufferOps
162               color_enter_op = EnterOp/Clear
163               color_exit_op = ExitOp/Read
164               depth_enter_op = EnterOp/Clear
165               depth_exit_op = ExitOp/Continue
166   
167           framebuffer = depth_framebuffer
168           pass = Renderer.opaque_pass
169   
170       let clear_color = Node/ClearColor (Vector4 0 0 0 1)
171       let opaque = Node/Render
172           ops = FramebufferOps
173               color_enter_op = EnterOp/Clear
174               color_exit_op = ExitOp/Continue
175               depth_enter_op = EnterOp/Continue
176               depth_exit_op = ExitOp/Continue
177   
178           framebuffer = color_framebuffer
179           pass = Renderer.opaque_pass
180   
181       let translucent = Node/Render
182           ops = FramebufferOps
183               color_enter_op = EnterOp/Continue
184               color_exit_op = ExitOp/Read
185               depth_enter_op = EnterOp/Continue
186               depth_exit_op = ExitOp/Read
187   
188           framebuffer = color_framebuffer
189           pass = Renderer.translucent_pass
190   
191       let tonemap = Node/Tonemap
192           framebuffer = tonemap_framebuffer
193           descriptor_set = tonemap_descriptor_set
194           =size
195           =max_size
196   
197       let nodes = mut_list_of
198           depth_pre_pass.as_node
199           Node/Barrier
200           clear_color.as_node
201           opaque.as_node
202           translucent.as_node
203   
204       if is_msaa then
205           let resolve_depth = Node/ResolveDepth
206               from = resolve_depth_source_descriptor_set
207               to = resolve_depth_destination_descriptor_set
208               =samples
209   
210           let resolve_multisample = Node/ResolveMultisample
211               from = color_msaa
212               to = color
213   
214           nodes.add resolve_depth
215           nodes.add resolve_multisample
216   
217       nodes.add tonemap
218   
219       let token = size.subscribe { _ x ->
220           tonemap_framebuffer.size = x
221           color_framebuffer.size = x
222           depth_framebuffer.size = x }
223   
224       (token, tonemap_color, nodes)
225   
226   object Renderer
227       def create (size : mut Atom<Size>
228                   camera : Camera
229                   lighting : Lighting
230                   field : Field
231                   nodes : List<Node>
232                   guards : List<Object -> bool>
233                   cull_mode : CullModeFlags
234                   maybe_blit_image : Option<BlitImage>) =
235           let scene_buffer = UniformBuffer.create (sizeof SceneUbo)
236           let passes = guards.map { Pass _ }
237   
238           Renderer =size =camera
239                    scene_ubo = SceneUbo.default
240                    =scene_buffer
241                    skin_buffer = null
242                    skin_buffer_size = 0
243                    =passes =lighting =field =nodes =cull_mode =maybe_blit_image
244