1     module draw
2     
3     let create_state (vulkan : Vulkan) =
4         assert vulkan.gpu_state.is_none
5     
6         vulkan.gpu_state = GpuState/Draw
7             command_buffer = vulkan.command_buffer.object
8             pipeline = null
9             vertex_buffer = null
10            index_buffer = null
11            index_count = 0
12            index_offset = 0
13            descriptor_set_states = memory@zero
14            pipeline_push_constant_stages = ShaderStageFlags@zero
15    
16    def set_push_constant<T> (data : Ptr<T>) =
17        let vulkan : Vulkan @auto
18        let state = vulkan.gpu_state.draw_mut
19    
20        vk/cmd_push_constants state.command_buffer state.pipeline.pipeline_layout
21                              state.pipeline_push_constant_stages 0 (sizeof T) data
22    
23    def draw =
24        let vulkan : Vulkan @auto
25    
26        let state = vulkan.gpu_state.draw_mut
27        bind_descriptor_sets state.command_buffer PipelineBindPoint/Graphics
28                             state.pipeline.pipeline_layout
29                             state.descriptor_set_states@mut_ref
30    
31        vk/cmd_draw_indexed state.command_buffer state.index_count 1
32                            state.index_offset 0 0
33    
34    def begin (framebuffer : Framebuffer
35               color_enter_op : EnterOp
36               color_exit_op : ExitOp
37               depth_enter_op : EnterOp
38               depth_exit_op : ExitOp
39               clear_colors : Slice<Vector4>) =
40        let vulkan : Vulkan @auto
41        create_state vulkan
42    
43        let clear_depth = 1
44        let clear_stencil = 0
45        let offset = Vector2i 0 0
46        let size = framebuffer.size
47    
48        if color_enter_op == EnterOp/Clear then
49            let count = framebuffer.images
50                        |> count { _.is_color_attachment }
51    
52            assert clear_colors.size == count
53    
54        let (vk_framebuffer, render_pass) =
55            framebuffer.get color_enter_op color_exit_op depth_enter_op depth_exit_op
56    
57        let command_buffer = vulkan.command_buffer.object
58        let clear_values = List<ClearValue>.new
59    
60        let mut color_index = 0
61        for image in framebuffer.images do
62            let clear_value = when
63                color_index < clear_colors.size as i32 && image.is_color_attachment ->
64                    let clear_color = clear_colors[color_index]
65                    color_index += 1
66                    ClearValue.color clear_color
67    
68                image.is_depth_attachment ->
69                    ClearValue.depth_stencil clear_depth clear_stencil
70    
71                else -> ClearValue.color Vector4.new
72    
73            clear_values.add clear_value
74    
75        let render_pass_begin_info = RenderPassBeginInfo
76            type = StructureType/RenderPassBeginInfo
77            next = null
78            render_pass = render_pass.object
79            framebuffer = vk_framebuffer
80            render_area = Rect2D.create 0 0 framebuffer.size.width
81                                        framebuffer.size.height
82    
83            clear_value_count = clear_values.size
84            clear_values = clear_values.as_ptr
85    
86        vk/cmd_begin_render_pass command_buffer
87                                 render_pass_begin_info@ptr
88                                 SubpassContents/Inline
89    
90        let viewport = Viewport
91            x = offset.x as f32
92            y = offset.y as f32
93            width = size.width as f32
94            height = size.height as f32
95            min_depth = 0
96            max_depth = 1
97    
98        vk/cmd_set_viewport command_buffer 0 1 viewport@ptr
99    
100       vulkan.framebuffer_scissor = Rect2D.create offset.x offset.y size.width
101                                                  size.height
102       render_pass
103   
104   def begin_for_swapchain (clear_color : Vector4) =
105       let vulkan : Vulkan @auto
106       create_state vulkan
107   
108       let command_buffer = vulkan.command_buffer.object
109       let width = vulkan.swapchain.width
110       let height = vulkan.swapchain.height
111   
112       let clear_values = [ClearValue.color clear_color
113                           ClearValue.color clear_color]
114   
115       let i = vulkan.swapchain.image_index
116       let render_pass_begin_info = RenderPassBeginInfo
117           type = StructureType/RenderPassBeginInfo
118           next = null
119           render_pass = vulkan.swapchain.render_pass
120           framebuffer = vulkan.swapchain.image_resources[i].framebuffer
121           render_area = Rect2D.create 0 0 width height
122           clear_value_count = clear_values.size
123           clear_values = clear_values.as_ptr
124   
125       vk/cmd_begin_render_pass command_buffer render_pass_begin_info@ptr
126                                SubpassContents/Inline
127   
128       let viewport = Viewport
129           x = 0
130           y = 0
131           width = width as f32
132           height = height as f32
133           min_depth = 0
134           max_depth = 1
135   
136       vk/cmd_set_viewport command_buffer 0 1 viewport@ptr
137       vulkan.framebuffer_scissor = Rect2D.create 0 0 width height
138   
139   def end =
140       let vulkan : Vulkan @auto
141       assert vulkan.gpu_state.is_draw
142       vulkan.gpu_state = GpuState/None
143       vk/cmd_end_render_pass vulkan.command_buffer.object
144