1 object Pipeline = 2 def create (vertex_shader : VertexShader 3 fragment_shader : FragmentShader 4 pipeline_layout : PipelineLayout 5 render_pass : RenderPass 6 vertex_format : VertexFormat 7 rasterization : Rasterization 8 multisample : Multisample 9 depth_stencil : DepthStencil 10 blend : ColorBlend 11 subpass : u32) = 12 let instance : Instance @auto 13 14 assert subpass < render_pass.format.subpasses.size 15 let subpass_format = render_pass.format.subpasses[subpass] 16 let output_mask = subpass_format.color_attachments 17 |> filter { _ <> Vulkan.attachment_unused } 18 |> with_index 19 |> fold 0 { acc (i, _) -> acc | 1 << i } 20 21 assert fragment_shader.output_mask == output_mask 22 23 let pipeline_vertex_input_state_create_info = if 24 vertex_format <> null 25 then 26 let input_mask = vertex_format.attribute_descriptions 27 |> fold 0 { acc x -> acc | 1 << x.location } 28 assert vertex_shader.input_mask & input_mask == vertex_shader.input_mask 29 30 PipelineVertexInputStateCreateInfo 31 type = StructureType/PipelineVertexInputStateCreateInfo 32 next = null 33 flags = PipelineVertexInputStateCreateFlags@zero 34 vertex_binding_description_count = 35 vertex_format.binding_descriptions.size 36 37 vertex_binding_descriptions = 38 vertex_format.binding_descriptions.ptr 39 40 vertex_attribute_description_count = 41 vertex_format.attribute_descriptions.size 42 43 vertex_attribute_descriptions = 44 vertex_format.attribute_descriptions.ptr 45 else 46 assert vertex_shader.input_mask == 0 47 PipelineVertexInputStateCreateInfo 48 type = StructureType/PipelineVertexInputStateCreateInfo 49 next = null 50 flags = PipelineVertexInputStateCreateFlags@zero 51 vertex_binding_description_count = 0 52 vertex_binding_descriptions = null 53 vertex_attribute_description_count = 0 54 vertex_attribute_descriptions = null 55 56 let input_assembly_create_info = PipelineInputAssemblyStateCreateInfo 57 type = StructureType/PipelineInputAssemblyStateCreateInfo 58 next = null 59 flags = PipelineInputAssemblyStateCreateFlags@zero 60 topology = PrimitiveTopology/TriangleList 61 primitive_restart_enable = 0 62 63 let viewport_state_create_info = PipelineViewportStateCreateInfo 64 type = StructureType/PipelineViewportStateCreateInfo 65 next = null 66 flags = PipelineViewportStateCreateFlags@zero 67 viewport_count = 1 68 viewports = null 69 scissor_count = 1 70 scissors = null 71 72 let rasterization_state_create_info = PipelineRasterizationStateCreateInfo 73 type = StructureType/PipelineRasterizationStateCreateInfo 74 next = null 75 flags = PipelineRasterizationStateCreateFlags@zero 76 depth_clamp_enable = if rasterization.enable_depth_clamp then 1 else 0 77 rasterizer_discard_enable = if rasterization.discard_primitives 78 then 1 79 else 0 80 81 polygon_mode = if rasterization.wireframe 82 then PolygonMode/Line 83 else PolygonMode/Fill 84 85 cull_mode = rasterization.cull_mode 86 front_face = rasterization.front_face 87 depth_bias_enable = if rasterization.depth_bias_enable then 1 else 0 88 depth_bias_constant_factor = rasterization.depth_bias_constant_factor 89 depth_bias_clamp = rasterization.depth_bias_clamp 90 depth_bias_slope_factor = rasterization.depth_bias_slope_factor 91 line_width = rasterization.line_width 92 93 let multisample_state_create_info = PipelineMultisampleStateCreateInfo 94 type = StructureType/PipelineMultisampleStateCreateInfo 95 next = null 96 flags = PipelineMultisampleStateCreateFlags@zero 97 rasterization_samples = multisample.samples 98 sample_shading_enable = if multisample.enable_sample_shading 99 then 1 100 else 0 101 102 min_sample_shading = multisample.min_sample_shading 103 sample_mask = null 104 alpha_to_coverage_enable = if multisample.enable_alpha_to_coverage 105 then 1 106 else 0 107 108 alpha_to_one_enable = if multisample.enable_alpha_to_one then 1 else 0 109 110 let depth_stencil_state_create_info = PipelineDepthStencilStateCreateInfo 111 type = StructureType/PipelineDepthStencilStateCreateInfo 112 next = null 113 flags = PipelineDepthStencilStateCreateFlags@zero 114 depth_test_enable = if depth_stencil.enable_depth_test then 1 else 0 115 depth_write_enable = if depth_stencil.enable_depth_write then 1 else 0 116 depth_compare_op = depth_stencil.depth_compare_operator 117 depth_bounds_test_enable = if depth_stencil.enable_depth_range 118 then 1 119 else 0 120 121 stencil_test_enable = if depth_stencil.enable_stencil then 1 else 0 122 front = StencilOpState 123 fail_op = depth_stencil.front_op.fail_op 124 pass_op = depth_stencil.front_op.pass_op 125 depth_fail_op = depth_stencil.front_op.depth_fail_op 126 compare_op = depth_stencil.front_op.compare_op 127 compare_mask = depth_stencil.front_op.compare_mask 128 write_mask = depth_stencil.front_op.write_mask 129 reference = depth_stencil.front_op.reference 130 131 back = StencilOpState 132 fail_op = depth_stencil.back_op.fail_op 133 pass_op = depth_stencil.back_op.pass_op 134 depth_fail_op = depth_stencil.back_op.depth_fail_op 135 compare_op = depth_stencil.back_op.compare_op 136 compare_mask = depth_stencil.back_op.compare_mask 137 write_mask = depth_stencil.back_op.write_mask 138 reference = depth_stencil.back_op.reference 139 140 min_depth_bounds = depth_stencil.depth_range_min 141 max_depth_bounds = depth_stencil.depth_range_max 142 143 let attachment_states = subpass_format.color_attachments 144 |> filter { _ <> Vulkan.attachment_unused } 145 |> with_index 146 |> map { i, _ -> 147 let attachment = blend.attachments[i] 148 let mut color_write_mask = ColorComponentFlags@zero 149 if attachment.write_r then 150 color_write_mask |= ColorComponentFlags/R 151 152 if attachment.write_g then 153 color_write_mask |= ColorComponentFlags/G 154 155 if attachment.write_b then 156 color_write_mask |= ColorComponentFlags/B 157 158 if attachment.write_a then 159 color_write_mask |= ColorComponentFlags/A 160 161 PipelineColorBlendAttachmentState 162 blend_enable = if attachment.enable_blend then 1 else 0 163 src_color_blend_factor = attachment.src_color_blend_factor 164 dst_color_blend_factor = attachment.dst_color_blend_factor 165 color_blend_op = attachment.color_blend_op 166 src_alpha_blend_factor = attachment.src_alpha_blend_factor 167 dst_alpha_blend_factor = attachment.dst_alpha_blend_factor 168 alpha_blend_op = attachment.alpha_blend_op 169 =color_write_mask } 170 171 assert attachment_states.size == blend.attachments.size 172 173 let color_blend_state_create_info = PipelineColorBlendStateCreateInfo 174 type = StructureType/PipelineColorBlendStateCreateInfo 175 next = null 176 flags = PipelineColorBlendStateCreateFlags@zero 177 logic_op_enable = if blend.enable_logic_op then 1 else 0 178 logic_op = blend.logic_op 179 attachment_count = attachment_states.size 180 attachments = attachment_states.as_ptr 181 blend_constants = [blend.blend_constant.x 182 blend.blend_constant.y 183 blend.blend_constant.z 184 blend.blend_constant.w] 185 186 let dynamic_states = [DynamicState/Viewport, DynamicState/Scissor] 187 let dynamic_state_create_info = PipelineDynamicStateCreateInfo 188 type = StructureType/PipelineDynamicStateCreateInfo 189 next = null 190 flags = PipelineDynamicStateCreateFlags@zero 191 dynamic_state_count = dynamic_states.size 192 dynamic_states = dynamic_states.as_ptr 193 194 let pipeline_stages = [vertex_shader.create_info, fragment_shader.create_info] 195 let graphics_pipeline_create_info = GraphicsPipelineCreateInfo 196 type = StructureType/GraphicsPipelineCreateInfo 197 next = null 198 flags = PipelineCreateFlags@zero 199 stage_count = pipeline_stages.size 200 stages = pipeline_stages.as_ptr 201 vertex_input_state = pipeline_vertex_input_state_create_info@ptr 202 input_assembly_state = input_assembly_create_info@ptr 203 tessellation_state = null 204 viewport_state = viewport_state_create_info@ptr 205 rasterization_state = rasterization_state_create_info@ptr 206 multisample_state = multisample_state_create_info@ptr 207 depth_stencil_state = depth_stencil_state_create_info@ptr 208 color_blend_state = color_blend_state_create_info@ptr 209 dynamic_state = dynamic_state_create_info@ptr 210 layout = pipeline_layout.object 211 render_pass = render_pass.object 212 =subpass 213 base_pipeline_handle = VkPipeline@zero 214 base_pipeline_index = 0 215 216 let mut pipeline = null 217 vk/create_graphics_pipelines instance.device VkPipelineCache@zero 1 218 graphics_pipeline_create_info@ptr null 219 pipeline@mut_ptr 220 |> assert_success 221 222 Pipeline =vertex_shader 223 =fragment_shader 224 pipeline_layout = pipeline_layout.object 225 object = pipeline 226 push_constant_size = pipeline_layout.push_constant_size 227 push_constant_stages = pipeline_layout.push_constant_stages 228