1use crate::{
2 Device, DeviceOwned, PipelineAccess, PipelineCache, PipelineLayout, RenderPass, ShaderStage,
3 ALLOCATION_CALLBACK_NONE,
4};
5use ash::{
6 prelude::VkResult,
7 vk::{self, Handle},
8};
9use std::sync::Arc;
10
11pub struct GraphicsPipeline {
12 handle: vk::Pipeline,
13 properties: GraphicsPipelineProperties,
14
15 pipeline_layout: Arc<PipelineLayout>,
17 }
19
20impl GraphicsPipeline {
21 pub fn new(
22 pipeline_layout: Arc<PipelineLayout>,
23 properties: GraphicsPipelineProperties,
24 shader_stages: &[ShaderStage],
25 render_pass: &RenderPass,
26 pipeline_cache: Option<&PipelineCache>,
27 ) -> VkResult<Self> {
28 let shader_stages_vk = shader_stages
30 .iter()
31 .map(|stage| stage.create_info_builder().build())
32 .collect::<Vec<vk::PipelineShaderStageCreateInfo>>();
33
34 let properties_vk = properties.vk_create_infos();
36
37 let create_info_builder = properties
39 .write_create_info_builder(vk::GraphicsPipelineCreateInfo::builder(), &properties_vk);
40 let create_info_builder = create_info_builder
41 .stages(&shader_stages_vk)
42 .render_pass(render_pass.handle())
43 .layout(pipeline_layout.handle());
44
45 let cache_handle = if let Some(pipeline_cache) = pipeline_cache {
46 pipeline_cache.handle()
47 } else {
48 vk::PipelineCache::null()
49 };
50
51 let handle_res = unsafe {
52 pipeline_layout.device().inner().create_graphics_pipelines(
53 cache_handle,
54 &[create_info_builder.build()],
55 ALLOCATION_CALLBACK_NONE,
56 )
57 };
58 let handle = handle_res.map_err(|(_pipelines, err_code)| err_code)?[0];
60
61 Ok(Self {
62 handle,
63 properties,
64 pipeline_layout,
65 })
66 }
67
68 pub unsafe fn new_from_create_info(
75 pipeline_layout: Arc<PipelineLayout>,
76 create_info_builder: vk::GraphicsPipelineCreateInfoBuilder,
77 pipeline_cache: Option<&PipelineCache>,
78 ) -> VkResult<Self> {
79 let properties =
80 unsafe { GraphicsPipelineProperties::from_create_info_builder(&create_info_builder) };
81
82 let cache_handle = if let Some(pipeline_cache) = pipeline_cache {
83 pipeline_cache.handle()
84 } else {
85 vk::PipelineCache::null()
86 };
87
88 let handle_res = unsafe {
89 pipeline_layout.device().inner().create_graphics_pipelines(
90 cache_handle,
91 &[create_info_builder.build()],
92 ALLOCATION_CALLBACK_NONE,
93 )
94 };
95 let handle = handle_res.map_err(|(_pipelines, err_code)| err_code)?[0];
97
98 Ok(Self {
99 handle,
100 properties,
101 pipeline_layout,
102 })
103 }
104
105 pub fn new_batch_create<'a>(
106 device: &Device,
107 per_pipeline_params: Vec<PerPipelineCreationParams<'a>>,
108 pipeline_cache: Option<&PipelineCache>,
109 ) -> VkResult<Vec<Self>> {
110 let pipeline_count = per_pipeline_params.len();
111
112 let mut pipeline_properties_vk = Vec::<GraphicsPipelinePropertiesCreateInfosVk>::new();
114 for pipeline_index in 0..pipeline_count {
115 let properties_vk = per_pipeline_params[pipeline_index]
116 .properties
117 .vk_create_infos();
118 pipeline_properties_vk.push(properties_vk);
119 }
120
121 let mut shader_stage_handles = Vec::<Vec<vk::PipelineShaderStageCreateInfo>>::new();
123 for pipeline_index in 0..pipeline_count {
124 let shader_stages_vk: Vec<vk::PipelineShaderStageCreateInfo> = per_pipeline_params
125 [pipeline_index]
126 .shader_stages
127 .iter()
128 .map(|stage| stage.create_info_builder().build())
129 .collect();
130 shader_stage_handles.push(shader_stages_vk);
131 }
132
133 let mut create_info_builders = Vec::<vk::GraphicsPipelineCreateInfoBuilder>::new();
135 for pipeline_index in 0..pipeline_count {
136 let create_info_builder = per_pipeline_params[pipeline_index]
137 .properties
138 .write_create_info_builder(
139 vk::GraphicsPipelineCreateInfo::builder(),
140 &pipeline_properties_vk[pipeline_index],
141 );
142
143 let create_info_builder = create_info_builder
144 .stages(&shader_stage_handles[pipeline_index])
145 .render_pass(per_pipeline_params[pipeline_index].render_pass.handle())
146 .layout(per_pipeline_params[pipeline_index].pipeline_layout.handle());
147
148 create_info_builders.push(create_info_builder);
149 }
150
151 let create_infos: Vec<vk::GraphicsPipelineCreateInfo> = create_info_builders
152 .into_iter()
153 .map(|builder| builder.build())
154 .collect();
155
156 let cache_handle = if let Some(pipeline_cache) = pipeline_cache {
157 pipeline_cache.handle()
158 } else {
159 vk::PipelineCache::null()
160 };
161
162 let pipeline_handles = unsafe {
163 device.inner().create_graphics_pipelines(
164 cache_handle,
165 &create_infos,
166 ALLOCATION_CALLBACK_NONE,
167 )
168 }
169 .map_err(|(_pipelines, err_code)| err_code)?; let pipelines: Vec<GraphicsPipeline> = per_pipeline_params
172 .into_iter()
173 .enumerate()
174 .map(|(index, params)| Self {
175 handle: pipeline_handles[index],
176 properties: params.properties,
177 pipeline_layout: params.pipeline_layout.clone(),
178 })
179 .collect();
180
181 Ok(pipelines)
182 }
183
184 #[inline]
187 pub fn properties(&self) -> &GraphicsPipelineProperties {
188 &self.properties
189 }
190}
191
192impl PipelineAccess for GraphicsPipeline {
193 #[inline]
194 fn handle(&self) -> vk::Pipeline {
195 self.handle
196 }
197
198 #[inline]
199 fn pipeline_layout(&self) -> &Arc<PipelineLayout> {
200 &self.pipeline_layout
201 }
202
203 #[inline]
204 fn bind_point(&self) -> vk::PipelineBindPoint {
205 vk::PipelineBindPoint::GRAPHICS
206 }
207}
208
209impl DeviceOwned for GraphicsPipeline {
210 #[inline]
211 fn device(&self) -> &Arc<Device> {
212 &self.pipeline_layout.device()
213 }
214
215 #[inline]
216 fn handle_raw(&self) -> u64 {
217 self.handle.as_raw()
218 }
219}
220
221impl Drop for GraphicsPipeline {
222 fn drop(&mut self) {
223 unsafe {
224 self.device()
225 .inner()
226 .destroy_pipeline(self.handle, ALLOCATION_CALLBACK_NONE)
227 }
228 }
229}
230
231trait FromCreateInfo<VkCreateInfo> {
235 fn from_create_info(value: &VkCreateInfo) -> Self;
236}
237
238unsafe fn from_create_info_ptr<Properties, VkCreateInfo>(
244 vk_create_info_ptr: *const VkCreateInfo,
245) -> Properties
246where
247 Properties: FromCreateInfo<VkCreateInfo> + Default,
248 VkCreateInfo: Copy + Clone,
249{
250 if vk_create_info_ptr != std::ptr::null() {
251 let vk_create_info = unsafe { *vk_create_info_ptr };
252 Properties::from_create_info(&vk_create_info)
253 } else {
254 Default::default()
255 }
256}
257
258#[derive(Debug, Clone, Default)]
262pub struct GraphicsPipelineProperties {
263 pub flags: vk::PipelineCreateFlags,
264 pub subpass_index: u32,
265 pub vertex_input_state: VertexInputState,
266 pub input_assembly_state: InputAssemblyState,
267 pub tessellation_state: TessellationState,
268 pub viewport_state: ViewportState,
269 pub rasterization_state: RasterizationState,
270 pub multisample_state: MultisampleState,
271 pub depth_stencil_state: DepthStencilState,
272 pub color_blend_state: ColorBlendState,
273 pub dynamic_state: DynamicState,
274}
275impl GraphicsPipelineProperties {
276 pub fn write_create_info_builder<'a>(
286 &'a self,
287 builder: vk::GraphicsPipelineCreateInfoBuilder<'a>,
288 properties_vk: &'a GraphicsPipelinePropertiesCreateInfosVk<'a>,
289 ) -> vk::GraphicsPipelineCreateInfoBuilder<'a> {
290 builder
292 .flags(self.flags)
293 .subpass(self.subpass_index)
294 .vertex_input_state(&properties_vk.vertex_input_state_vk)
295 .input_assembly_state(&properties_vk.input_assembly_state_vk)
296 .tessellation_state(&properties_vk.tessellation_state_vk)
297 .viewport_state(&properties_vk.viewport_state_vk)
298 .rasterization_state(&properties_vk.rasterization_state_vk)
299 .multisample_state(&properties_vk.multisample_state_vk)
300 .depth_stencil_state(&properties_vk.depth_stencil_state_vk)
301 .color_blend_state(&properties_vk.color_blend_state_vk)
302 .dynamic_state(&properties_vk.dynamic_state_vk)
303 }
304
305 pub fn vk_create_infos<'a>(&'a self) -> GraphicsPipelinePropertiesCreateInfosVk<'a> {
308 let mut properties_vk = GraphicsPipelinePropertiesCreateInfosVk::default();
309 properties_vk.vertex_input_state_vk = self.vertex_input_state.create_info_builder();
311 properties_vk.input_assembly_state_vk = self.input_assembly_state.create_info_builder();
312 properties_vk.tessellation_state_vk = self.tessellation_state.create_info_builder();
313 properties_vk.viewport_state_vk = self.viewport_state.create_info_builder();
314 properties_vk.rasterization_state_vk = self.rasterization_state.create_info_builder();
315 properties_vk.multisample_state_vk = self.multisample_state.create_info_builder();
316 properties_vk.depth_stencil_state_vk = self.depth_stencil_state.create_info_builder();
317 properties_vk.color_blend_state_vk = self.color_blend_state.create_info_builder();
318 properties_vk.dynamic_state_vk = self.dynamic_state.create_info_builder();
319 properties_vk
320 }
321
322 pub unsafe fn from_create_info(value: &vk::GraphicsPipelineCreateInfo) -> Self {
340 let vertex_input_state = if value.p_vertex_input_state != std::ptr::null() {
341 let vk_create_info = unsafe { *value.p_vertex_input_state };
342 VertexInputState::from_create_info(&vk_create_info)
343 } else {
344 Default::default()
345 };
346 let input_assembly_state = from_create_info_ptr(value.p_input_assembly_state);
347 let tessellation_state = from_create_info_ptr(value.p_tessellation_state);
348 let viewport_state = if value.p_viewport_state != std::ptr::null() {
349 let vk_create_info = unsafe { *value.p_viewport_state };
350 ViewportState::from_create_info(&vk_create_info)
351 } else {
352 Default::default()
353 };
354 let rasterization_state = from_create_info_ptr(value.p_rasterization_state);
355 let multisample_state = if value.p_multisample_state != std::ptr::null() {
356 let vk_create_info = unsafe { *value.p_multisample_state };
357 MultisampleState::from_create_info(&vk_create_info)
358 } else {
359 Default::default()
360 };
361 let depth_stencil_state = from_create_info_ptr(value.p_depth_stencil_state);
362 let color_blend_state = if value.p_color_blend_state != std::ptr::null() {
363 let vk_create_info = unsafe { *value.p_color_blend_state };
364 ColorBlendState::from_create_info(&vk_create_info)
365 } else {
366 Default::default()
367 };
368 let dynamic_state = if value.p_dynamic_state != std::ptr::null() {
369 let vk_create_info = unsafe { *value.p_dynamic_state };
370 DynamicState::from_create_info(&vk_create_info)
371 } else {
372 Default::default()
373 };
374
375 Self {
376 flags: value.flags,
377 subpass_index: value.subpass,
378 vertex_input_state,
379 input_assembly_state,
380 tessellation_state,
381 viewport_state,
382 rasterization_state,
383 multisample_state,
384 depth_stencil_state,
385 color_blend_state,
386 dynamic_state,
387 }
388 }
389
390 pub unsafe fn from_create_info_builder(value: &vk::GraphicsPipelineCreateInfoBuilder) -> Self {
397 Self::from_create_info(value)
398 }
399}
400
401#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPipelineColorBlendAttachmentState.html>"]
404#[derive(Debug, Clone)]
405pub struct ColorBlendState {
406 pub flags: vk::PipelineColorBlendStateCreateFlags,
407 pub logic_op: Option<vk::LogicOp>,
408 pub attachments: Vec<vk::PipelineColorBlendAttachmentState>,
409 pub blend_constants: [f32; 4],
410}
411impl Default for ColorBlendState {
412 fn default() -> Self {
413 Self {
414 flags: vk::PipelineColorBlendStateCreateFlags::empty(),
415 logic_op: None,
416 attachments: Vec::new(),
417 blend_constants: [0.; 4],
418 }
419 }
420}
421impl ColorBlendState {
422 pub fn new_default(attachments: Vec<vk::PipelineColorBlendAttachmentState>) -> Self {
423 Self {
424 attachments,
425 ..Default::default()
426 }
427 }
428
429 pub fn write_create_info_builder<'a>(
430 &'a self,
431 builder: vk::PipelineColorBlendStateCreateInfoBuilder<'a>,
432 ) -> vk::PipelineColorBlendStateCreateInfoBuilder<'a> {
433 builder
434 .flags(self.flags)
435 .logic_op_enable(self.logic_op.is_some())
436 .logic_op(self.logic_op.unwrap_or(vk::LogicOp::CLEAR))
437 .attachments(&self.attachments)
438 .blend_constants(self.blend_constants)
439 }
440
441 pub fn create_info_builder(&self) -> vk::PipelineColorBlendStateCreateInfoBuilder {
442 self.write_create_info_builder(vk::PipelineColorBlendStateCreateInfo::builder())
443 }
444
445 pub fn blend_state_disabled() -> vk::PipelineColorBlendAttachmentState {
448 vk::PipelineColorBlendAttachmentState {
449 color_write_mask: vk::ColorComponentFlags::RGBA,
450 ..Default::default()
451 }
452 }
453
454 pub fn blend_state_ignore_source() -> vk::PipelineColorBlendAttachmentState {
457 vk::PipelineColorBlendAttachmentState {
458 blend_enable: 1,
459 color_blend_op: vk::BlendOp::ADD,
460 src_color_blend_factor: vk::BlendFactor::ZERO,
461 src_alpha_blend_factor: vk::BlendFactor::DST_COLOR,
462 alpha_blend_op: vk::BlendOp::ADD,
463 dst_color_blend_factor: vk::BlendFactor::ZERO,
464 dst_alpha_blend_factor: vk::BlendFactor::DST_COLOR,
465 color_write_mask: vk::ColorComponentFlags::RGBA,
466 ..Default::default()
467 }
468 }
469
470 pub fn blend_state_additive() -> vk::PipelineColorBlendAttachmentState {
473 vk::PipelineColorBlendAttachmentState {
474 blend_enable: 1,
475 color_blend_op: vk::BlendOp::ADD,
476 src_color_blend_factor: vk::BlendFactor::ONE,
477 src_alpha_blend_factor: vk::BlendFactor::ONE,
478 alpha_blend_op: vk::BlendOp::MAX,
479 dst_color_blend_factor: vk::BlendFactor::ONE,
480 dst_alpha_blend_factor: vk::BlendFactor::ONE,
481 color_write_mask: vk::ColorComponentFlags::RGBA,
482 ..Default::default()
483 }
484 }
485
486 pub unsafe fn from_create_info(value: &vk::PipelineColorBlendStateCreateInfo) -> Self {
489 let mut attachments = Vec::<vk::PipelineColorBlendAttachmentState>::new();
490 for i in 0..value.attachment_count {
491 let attachment_state = unsafe { *value.p_attachments.offset(i as isize) };
492 attachments.push(attachment_state);
493 }
494
495 let logic_op = if value.logic_op_enable == 0 {
496 None
497 } else {
498 Some(value.logic_op)
499 };
500
501 Self {
502 flags: value.flags,
503 logic_op,
504 attachments,
505 blend_constants: value.blend_constants,
506 }
507 }
508
509 pub fn from_create_info_builder(value: &vk::PipelineColorBlendStateCreateInfoBuilder) -> Self {
510 unsafe { Self::from_create_info(value) }
511 }
512}
513
514#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPipelineDepthStencilStateCreateInfo.html>"]
515#[derive(Debug, Clone)]
516pub struct DepthStencilState {
517 pub flags: vk::PipelineDepthStencilStateCreateFlags,
518 pub depth_test_enable: bool,
519 pub depth_write_enable: bool,
520 pub depth_compare_op: vk::CompareOp,
521 pub depth_bounds_test_enable: bool,
522 pub stencil_test_enable: bool,
523 pub front: vk::StencilOpState,
524 pub back: vk::StencilOpState,
525 pub min_depth_bounds: f32,
526 pub max_depth_bounds: f32,
527}
528impl Default for DepthStencilState {
529 fn default() -> Self {
530 Self {
531 flags: vk::PipelineDepthStencilStateCreateFlags::empty(),
532 depth_test_enable: false,
533 depth_write_enable: false,
534 depth_compare_op: vk::CompareOp::ALWAYS,
535 depth_bounds_test_enable: false,
536 stencil_test_enable: false,
537 front: vk::StencilOpState::default(),
538 back: vk::StencilOpState::default(),
539 min_depth_bounds: 0.,
540 max_depth_bounds: 0.,
541 }
542 }
543}
544impl DepthStencilState {
545 pub fn write_create_info_builder<'a>(
546 &self,
547 builder: vk::PipelineDepthStencilStateCreateInfoBuilder<'a>,
548 ) -> vk::PipelineDepthStencilStateCreateInfoBuilder<'a> {
549 builder
550 .flags(self.flags)
551 .depth_test_enable(self.depth_test_enable)
552 .depth_write_enable(self.depth_write_enable)
553 .depth_compare_op(self.depth_compare_op)
554 .depth_bounds_test_enable(self.depth_bounds_test_enable)
555 .stencil_test_enable(self.depth_bounds_test_enable)
556 .front(self.front)
557 .back(self.back)
558 .min_depth_bounds(self.min_depth_bounds)
559 .max_depth_bounds(self.max_depth_bounds)
560 }
561
562 pub fn create_info_builder(&self) -> vk::PipelineDepthStencilStateCreateInfoBuilder {
563 self.write_create_info_builder(vk::PipelineDepthStencilStateCreateInfo::builder())
564 }
565
566 pub fn from_create_info_builder(
567 value: &vk::PipelineDepthStencilStateCreateInfoBuilder,
568 ) -> Self {
569 Self::from_create_info(value)
570 }
571}
572impl FromCreateInfo<vk::PipelineDepthStencilStateCreateInfo> for DepthStencilState {
573 fn from_create_info(value: &vk::PipelineDepthStencilStateCreateInfo) -> Self {
574 Self {
575 flags: value.flags,
576 depth_test_enable: value.depth_test_enable != 0,
577 depth_write_enable: value.depth_write_enable != 0,
578 depth_compare_op: value.depth_compare_op,
579 depth_bounds_test_enable: value.depth_bounds_test_enable != 0,
580 stencil_test_enable: value.stencil_test_enable != 0,
581 front: value.front,
582 back: value.back,
583 min_depth_bounds: value.min_depth_bounds,
584 max_depth_bounds: value.max_depth_bounds,
585 }
586 }
587}
588
589#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPipelineDynamicStateCreateInfo.html>"]
590#[derive(Debug, Clone)]
591pub struct DynamicState {
592 pub flags: vk::PipelineDynamicStateCreateFlags,
593 pub dynamic_states: Vec<vk::DynamicState>,
594}
595impl Default for DynamicState {
596 fn default() -> Self {
597 Self {
598 flags: vk::PipelineDynamicStateCreateFlags::empty(),
599 dynamic_states: Vec::new(),
600 }
601 }
602}
603impl DynamicState {
604 pub fn new_default(dynamic_states: Vec<vk::DynamicState>) -> Self {
605 Self {
606 dynamic_states,
607 ..Default::default()
608 }
609 }
610
611 pub fn write_create_info_builder<'a>(
612 &'a self,
613 builder: vk::PipelineDynamicStateCreateInfoBuilder<'a>,
614 ) -> vk::PipelineDynamicStateCreateInfoBuilder<'a> {
615 builder
616 .flags(self.flags)
617 .dynamic_states(&self.dynamic_states)
618 }
619
620 pub fn create_info_builder(&self) -> vk::PipelineDynamicStateCreateInfoBuilder {
621 self.write_create_info_builder(vk::PipelineDynamicStateCreateInfo::builder())
622 }
623
624 pub unsafe fn from_create_info(value: &vk::PipelineDynamicStateCreateInfo) -> Self {
627 let mut dynamic_states = Vec::<vk::DynamicState>::new();
628 for i in 0..value.dynamic_state_count {
629 let dynamic_state = unsafe { *value.p_dynamic_states.offset(i as isize) };
630 dynamic_states.push(dynamic_state);
631 }
632
633 Self {
634 flags: value.flags,
635 dynamic_states,
636 }
637 }
638
639 pub fn from_create_info_builder(value: &vk::PipelineDynamicStateCreateInfoBuilder) -> Self {
640 unsafe { Self::from_create_info(value) }
641 }
642}
643
644#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPipelineInputAssemblyStateCreateInfo.html>"]
645#[derive(Debug, Clone)]
646pub struct InputAssemblyState {
647 pub flags: vk::PipelineInputAssemblyStateCreateFlags,
648 pub topology: vk::PrimitiveTopology,
649 pub primitive_restart_enable: bool,
650}
651impl Default for InputAssemblyState {
652 fn default() -> Self {
653 Self {
654 flags: vk::PipelineInputAssemblyStateCreateFlags::empty(),
655 topology: vk::PrimitiveTopology::TRIANGLE_LIST,
656 primitive_restart_enable: false,
657 }
658 }
659}
660impl InputAssemblyState {
661 pub fn write_create_info_builder<'a>(
662 &self,
663 builder: vk::PipelineInputAssemblyStateCreateInfoBuilder<'a>,
664 ) -> vk::PipelineInputAssemblyStateCreateInfoBuilder<'a> {
665 builder
666 .flags(self.flags)
667 .topology(self.topology)
668 .primitive_restart_enable(self.primitive_restart_enable)
669 }
670
671 pub fn create_info_builder(&self) -> vk::PipelineInputAssemblyStateCreateInfoBuilder {
672 self.write_create_info_builder(vk::PipelineInputAssemblyStateCreateInfo::builder())
673 }
674
675 pub fn from_create_info_builder(
676 value: &vk::PipelineInputAssemblyStateCreateInfoBuilder,
677 ) -> Self {
678 Self::from_create_info(value)
679 }
680}
681impl FromCreateInfo<vk::PipelineInputAssemblyStateCreateInfo> for InputAssemblyState {
682 fn from_create_info(value: &vk::PipelineInputAssemblyStateCreateInfo) -> Self {
683 Self {
684 flags: value.flags,
685 topology: value.topology,
686 primitive_restart_enable: value.primitive_restart_enable != 0,
687 }
688 }
689}
690
691#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPipelineMultisampleStateCreateInfo.html>"]
692#[derive(Debug, Clone)]
693pub struct MultisampleState {
694 pub flags: vk::PipelineMultisampleStateCreateFlags,
695 pub rasterization_samples: vk::SampleCountFlags,
696 pub sample_shading_enable: bool,
697 pub min_sample_shading: f32,
698 pub sample_mask: Vec<vk::SampleMask>,
699 pub alpha_to_coverage_enable: bool,
700 pub alpha_to_one_enable: bool,
701}
702impl Default for MultisampleState {
703 fn default() -> Self {
704 Self {
705 flags: vk::PipelineMultisampleStateCreateFlags::empty(),
706 rasterization_samples: vk::SampleCountFlags::TYPE_1,
707 sample_shading_enable: false,
708 min_sample_shading: 1.,
709 sample_mask: Vec::new(),
710 alpha_to_coverage_enable: false,
711 alpha_to_one_enable: false,
712 }
713 }
714}
715impl MultisampleState {
716 pub fn write_create_info_builder<'a>(
717 &'a self,
718 builder: vk::PipelineMultisampleStateCreateInfoBuilder<'a>,
719 ) -> vk::PipelineMultisampleStateCreateInfoBuilder<'a> {
720 builder
721 .flags(self.flags)
722 .rasterization_samples(self.rasterization_samples)
723 .sample_shading_enable(self.sample_shading_enable)
724 .min_sample_shading(self.min_sample_shading)
725 .sample_mask(&self.sample_mask)
726 .alpha_to_coverage_enable(self.alpha_to_coverage_enable)
727 .alpha_to_one_enable(self.alpha_to_one_enable)
728 }
729
730 pub fn create_info_builder(&self) -> vk::PipelineMultisampleStateCreateInfoBuilder {
731 self.write_create_info_builder(vk::PipelineMultisampleStateCreateInfo::builder())
732 }
733
734 pub unsafe fn from_create_info(value: &vk::PipelineMultisampleStateCreateInfo) -> Self {
739 let mut sample_mask = Vec::<vk::SampleMask>::new();
740 if value.p_sample_mask != std::ptr::null() {
741 let lower_32_bit_sample_mask = unsafe { *value.p_sample_mask };
742 sample_mask.push(lower_32_bit_sample_mask);
743
744 if value.rasterization_samples == vk::SampleCountFlags::TYPE_64 {
745 let upper_32_bit_sample_mask = unsafe { *value.p_sample_mask.offset(1) };
746 sample_mask.push(upper_32_bit_sample_mask);
747 }
748 }
749
750 Self {
751 flags: value.flags,
752 rasterization_samples: value.rasterization_samples,
753 sample_shading_enable: value.sample_shading_enable != 0,
754 min_sample_shading: value.min_sample_shading,
755 sample_mask,
756 alpha_to_coverage_enable: value.alpha_to_coverage_enable != 0,
757 alpha_to_one_enable: value.alpha_to_one_enable != 0,
758 }
759 }
760
761 pub fn from_create_info_builder(value: &vk::PipelineMultisampleStateCreateInfoBuilder) -> Self {
765 let mut sample_mask = Vec::<vk::SampleMask>::new();
766 if value.p_sample_mask != std::ptr::null() {
767 let lower_32_bit_sample_mask = unsafe { *value.p_sample_mask };
771 sample_mask.push(lower_32_bit_sample_mask);
772 }
773
774 Self {
775 flags: value.flags,
776 rasterization_samples: value.rasterization_samples,
777 sample_shading_enable: value.sample_shading_enable != 0,
778 min_sample_shading: value.min_sample_shading,
779 sample_mask,
780 alpha_to_coverage_enable: value.alpha_to_coverage_enable != 0,
781 alpha_to_one_enable: value.alpha_to_one_enable != 0,
782 }
783 }
784}
785
786#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPipelineRasterizationStateCreateInfo.html>"]
787#[derive(Debug, Clone)]
788pub struct RasterizationState {
789 pub flags: vk::PipelineRasterizationStateCreateFlags,
790 pub depth_clamp_enable: bool,
791 pub rasterizer_discard_enable: bool,
792 pub polygon_mode: vk::PolygonMode,
793 pub cull_mode: vk::CullModeFlags,
794 pub front_face: vk::FrontFace,
795 pub depth_bias_enable: bool,
796 pub depth_bias_constant_factor: f32,
797 pub depth_bias_clamp: f32,
798 pub depth_bias_slope_factor: f32,
799 pub line_width: f32,
800}
801impl Default for RasterizationState {
802 fn default() -> Self {
803 Self {
804 flags: vk::PipelineRasterizationStateCreateFlags::empty(),
805 depth_clamp_enable: false,
806 rasterizer_discard_enable: false,
807 polygon_mode: vk::PolygonMode::FILL,
808 cull_mode: vk::CullModeFlags::NONE,
809 front_face: vk::FrontFace::COUNTER_CLOCKWISE,
810 depth_bias_enable: false,
811 depth_bias_constant_factor: 1.,
812 depth_bias_clamp: 0.,
813 depth_bias_slope_factor: 1.,
814 line_width: 1.,
815 }
816 }
817}
818impl RasterizationState {
819 pub fn write_create_info_builder<'a>(
820 &self,
821 builder: vk::PipelineRasterizationStateCreateInfoBuilder<'a>,
822 ) -> vk::PipelineRasterizationStateCreateInfoBuilder<'a> {
823 builder
824 .flags(self.flags)
825 .depth_clamp_enable(self.depth_clamp_enable)
826 .rasterizer_discard_enable(self.rasterizer_discard_enable)
827 .polygon_mode(self.polygon_mode)
828 .cull_mode(self.cull_mode)
829 .front_face(self.front_face)
830 .depth_bias_enable(self.depth_bias_enable)
831 .depth_bias_constant_factor(self.depth_bias_constant_factor)
832 .depth_bias_clamp(self.depth_bias_clamp)
833 .depth_bias_slope_factor(self.depth_bias_slope_factor)
834 .line_width(self.line_width)
835 }
836
837 pub fn create_info_builder(&self) -> vk::PipelineRasterizationStateCreateInfoBuilder {
838 self.write_create_info_builder(vk::PipelineRasterizationStateCreateInfo::builder())
839 }
840
841 pub fn from_create_info_builder(
842 value: &vk::PipelineRasterizationStateCreateInfoBuilder,
843 ) -> Self {
844 Self::from_create_info(value)
845 }
846}
847impl FromCreateInfo<vk::PipelineRasterizationStateCreateInfo> for RasterizationState {
848 fn from_create_info(value: &vk::PipelineRasterizationStateCreateInfo) -> Self {
849 Self {
850 flags: value.flags,
851 depth_clamp_enable: value.depth_clamp_enable != 0,
852 rasterizer_discard_enable: value.rasterizer_discard_enable != 0,
853 polygon_mode: value.polygon_mode,
854 cull_mode: value.cull_mode,
855 front_face: value.front_face,
856 depth_bias_enable: value.depth_bias_enable != 0,
857 depth_bias_constant_factor: value.depth_bias_constant_factor,
858 depth_bias_clamp: value.depth_bias_clamp,
859 depth_bias_slope_factor: value.depth_bias_slope_factor,
860 line_width: value.line_width,
861 }
862 }
863}
864
865#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPipelineTessellationStateCreateInfo.html>"]
866#[derive(Debug, Clone)]
867pub struct TessellationState {
868 pub flags: vk::PipelineTessellationStateCreateFlags,
869 pub patch_control_points: u32,
870}
871impl Default for TessellationState {
872 fn default() -> Self {
873 Self {
874 flags: vk::PipelineTessellationStateCreateFlags::empty(),
875 patch_control_points: 0,
876 }
877 }
878}
879impl TessellationState {
880 pub fn write_create_info_builder<'a>(
881 &self,
882 builder: vk::PipelineTessellationStateCreateInfoBuilder<'a>,
883 ) -> vk::PipelineTessellationStateCreateInfoBuilder<'a> {
884 builder
885 .flags(self.flags)
886 .patch_control_points(self.patch_control_points)
887 }
888
889 pub fn create_info_builder(&self) -> vk::PipelineTessellationStateCreateInfoBuilder {
890 self.write_create_info_builder(vk::PipelineTessellationStateCreateInfo::builder())
891 }
892
893 pub fn from_create_info_builder(
894 value: &vk::PipelineTessellationStateCreateInfoBuilder,
895 ) -> Self {
896 Self::from_create_info(value)
897 }
898}
899impl FromCreateInfo<vk::PipelineTessellationStateCreateInfo> for TessellationState {
900 fn from_create_info(value: &vk::PipelineTessellationStateCreateInfo) -> Self {
901 Self {
902 flags: value.flags,
903 patch_control_points: value.patch_control_points,
904 }
905 }
906}
907
908#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPipelineVertexInputStateCreateInfo.html>"]
909#[derive(Debug, Clone)]
910pub struct VertexInputState {
911 pub flags: vk::PipelineVertexInputStateCreateFlags,
912 pub vertex_binding_descriptions: Vec<vk::VertexInputBindingDescription>,
913 pub vertex_attribute_descriptions: Vec<vk::VertexInputAttributeDescription>,
914}
915impl Default for VertexInputState {
916 fn default() -> Self {
917 Self {
918 flags: vk::PipelineVertexInputStateCreateFlags::empty(),
919 vertex_binding_descriptions: Vec::new(),
920 vertex_attribute_descriptions: Vec::new(),
921 }
922 }
923}
924impl VertexInputState {
925 pub fn write_create_info_builder<'a>(
926 &'a self,
927 builder: vk::PipelineVertexInputStateCreateInfoBuilder<'a>,
928 ) -> vk::PipelineVertexInputStateCreateInfoBuilder<'a> {
929 builder
930 .flags(self.flags)
931 .vertex_binding_descriptions(&self.vertex_binding_descriptions)
932 .vertex_attribute_descriptions(&self.vertex_attribute_descriptions)
933 }
934
935 pub fn create_info_builder(&self) -> vk::PipelineVertexInputStateCreateInfoBuilder {
936 self.write_create_info_builder(vk::PipelineVertexInputStateCreateInfo::builder())
937 }
938
939 pub unsafe fn from_create_info(value: &vk::PipelineVertexInputStateCreateInfo) -> Self {
943 let mut vertex_binding_descriptions = Vec::<vk::VertexInputBindingDescription>::new();
944 for i in 0..value.vertex_binding_description_count {
945 let binding_description =
946 unsafe { *value.p_vertex_binding_descriptions.offset(i as isize) };
947 vertex_binding_descriptions.push(binding_description);
948 }
949
950 let mut vertex_attribute_descriptions = Vec::<vk::VertexInputAttributeDescription>::new();
951 for i in 0..value.vertex_attribute_description_count {
952 let attribute_description =
953 unsafe { *value.p_vertex_attribute_descriptions.offset(i as isize) };
954 vertex_attribute_descriptions.push(attribute_description);
955 }
956
957 Self {
958 flags: value.flags,
959 vertex_binding_descriptions,
960 vertex_attribute_descriptions,
961 }
962 }
963
964 pub fn from_create_info_builder(value: &vk::PipelineVertexInputStateCreateInfoBuilder) -> Self {
965 unsafe { Self::from_create_info(value) }
966 }
967}
968
969#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPipelineViewportStateCreateInfo.html>"]
970#[derive(Debug, Clone)]
971pub struct ViewportState {
972 pub flags: vk::PipelineViewportStateCreateFlags,
973 pub viewports: Vec<vk::Viewport>,
974 pub scissors: Vec<vk::Rect2D>,
975}
976impl Default for ViewportState {
977 fn default() -> Self {
978 Self {
979 flags: vk::PipelineViewportStateCreateFlags::empty(),
980 viewports: Vec::new(),
981 scissors: Vec::new(),
982 }
983 }
984}
985impl ViewportState {
986 pub fn new_dynamic(viewport_count: usize, scissor_count: usize) -> Self {
987 Self {
988 viewports: vec![Default::default(); viewport_count],
989 scissors: vec![Default::default(); scissor_count],
990 ..Default::default()
991 }
992 }
993
994 pub fn write_create_info_builder<'a>(
995 &'a self,
996 builder: vk::PipelineViewportStateCreateInfoBuilder<'a>,
997 ) -> vk::PipelineViewportStateCreateInfoBuilder<'a> {
998 builder
999 .flags(self.flags)
1000 .viewports(&self.viewports)
1001 .scissors(&self.scissors)
1002 }
1003
1004 pub fn create_info_builder(&self) -> vk::PipelineViewportStateCreateInfoBuilder {
1005 self.write_create_info_builder(vk::PipelineViewportStateCreateInfo::builder())
1006 }
1007
1008 pub unsafe fn from_create_info(value: &vk::PipelineViewportStateCreateInfo) -> Self {
1012 let mut viewports = Vec::<vk::Viewport>::new();
1013 for i in 0..value.viewport_count {
1014 let viewport = unsafe { *value.p_viewports.offset(i as isize) };
1015 viewports.push(viewport);
1016 }
1017
1018 let mut scissors = Vec::<vk::Rect2D>::new();
1019 for i in 0..value.scissor_count {
1020 let scissor = unsafe { *value.p_scissors.offset(i as isize) };
1021 scissors.push(scissor);
1022 }
1023
1024 Self {
1025 flags: value.flags,
1026 viewports,
1027 scissors,
1028 }
1029 }
1030
1031 pub fn from_create_info_builder(value: &vk::PipelineViewportStateCreateInfoBuilder) -> Self {
1032 unsafe { Self::from_create_info(value) }
1033 }
1034}
1035
1036#[derive(Clone)]
1040pub struct PerPipelineCreationParams<'a> {
1041 pipeline_layout: Arc<PipelineLayout>,
1042 properties: GraphicsPipelineProperties,
1043 shader_stages: Vec<ShaderStage>,
1044 render_pass: &'a RenderPass,
1045}
1046
1047pub struct GraphicsPipelinePropertiesCreateInfosVk<'a> {
1053 pub vertex_input_state_vk: vk::PipelineVertexInputStateCreateInfoBuilder<'a>,
1054 pub input_assembly_state_vk: vk::PipelineInputAssemblyStateCreateInfoBuilder<'a>,
1055 pub tessellation_state_vk: vk::PipelineTessellationStateCreateInfoBuilder<'a>,
1056 pub viewport_state_vk: vk::PipelineViewportStateCreateInfoBuilder<'a>,
1057 pub rasterization_state_vk: vk::PipelineRasterizationStateCreateInfoBuilder<'a>,
1058 pub multisample_state_vk: vk::PipelineMultisampleStateCreateInfoBuilder<'a>,
1059 pub depth_stencil_state_vk: vk::PipelineDepthStencilStateCreateInfoBuilder<'a>,
1060 pub color_blend_state_vk: vk::PipelineColorBlendStateCreateInfoBuilder<'a>,
1061 pub dynamic_state_vk: vk::PipelineDynamicStateCreateInfoBuilder<'a>,
1062}
1063impl<'a> Default for GraphicsPipelinePropertiesCreateInfosVk<'a> {
1064 fn default() -> Self {
1065 Self {
1066 vertex_input_state_vk: vk::PipelineVertexInputStateCreateInfo::builder(),
1067 input_assembly_state_vk: vk::PipelineInputAssemblyStateCreateInfo::builder(),
1068 tessellation_state_vk: vk::PipelineTessellationStateCreateInfo::builder(),
1069 viewport_state_vk: vk::PipelineViewportStateCreateInfo::builder(),
1070 rasterization_state_vk: vk::PipelineRasterizationStateCreateInfo::builder(),
1071 multisample_state_vk: vk::PipelineMultisampleStateCreateInfo::builder(),
1072 depth_stencil_state_vk: vk::PipelineDepthStencilStateCreateInfo::builder(),
1073 color_blend_state_vk: vk::PipelineColorBlendStateCreateInfo::builder(),
1074 dynamic_state_vk: vk::PipelineDynamicStateCreateInfo::builder(),
1075 }
1076 }
1077}