1 // Copyright (c) 2022 The vulkano developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or
4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
6 // at your option. All files in the project carrying such
7 // notice may not be copied, modified, or distributed except
8 // according to those terms.
9 
10 use crate::{
11     command_buffer::{CommandBufferInheritanceRenderingInfo, RenderingInfo},
12     format::Format,
13     image::ImageAspects,
14     render_pass::Subpass,
15 };
16 
17 /// Selects the type of render pass that a graphics pipeline is created for.
18 #[derive(Clone, Debug)]
19 pub enum PipelineRenderPassType {
20     BeginRenderPass(Subpass),
21     BeginRendering(PipelineRenderingCreateInfo),
22 }
23 
24 impl From<Subpass> for PipelineRenderPassType {
25     #[inline]
from(val: Subpass) -> Self26     fn from(val: Subpass) -> Self {
27         Self::BeginRenderPass(val)
28     }
29 }
30 
31 impl From<PipelineRenderingCreateInfo> for PipelineRenderPassType {
32     #[inline]
from(val: PipelineRenderingCreateInfo) -> Self33     fn from(val: PipelineRenderingCreateInfo) -> Self {
34         Self::BeginRendering(val)
35     }
36 }
37 
38 /// The dynamic rendering parameters to create a graphics pipeline.
39 #[derive(Clone, Debug)]
40 pub struct PipelineRenderingCreateInfo {
41     /// If not `0`, indicates that multiview rendering will be enabled, and specifies the view
42     /// indices that are rendered to. The value is a bitmask, so that that for example `0b11` will
43     /// draw to the first two views and `0b101` will draw to the first and third view.
44     ///
45     /// If set to a nonzero value, the [`multiview`](crate::device::Features::multiview) feature
46     /// must be enabled on the device.
47     ///
48     /// The default value is `0`.
49     pub view_mask: u32,
50 
51     /// The formats of the color attachments that will be used during rendering.
52     ///
53     /// If an element is `None`, it indicates that the attachment will not be used.
54     ///
55     /// The default value is empty.
56     pub color_attachment_formats: Vec<Option<Format>>,
57 
58     /// The format of the depth attachment that will be used during rendering.
59     ///
60     /// If set to `None`, it indicates that no depth attachment will be used.
61     ///
62     /// The default value is `None`.
63     pub depth_attachment_format: Option<Format>,
64 
65     /// The format of the stencil attachment that will be used during rendering.
66     ///
67     /// If set to `None`, it indicates that no stencil attachment will be used.
68     ///
69     /// The default value is `None`.
70     pub stencil_attachment_format: Option<Format>,
71 
72     pub _ne: crate::NonExhaustive,
73 }
74 
75 impl Default for PipelineRenderingCreateInfo {
76     #[inline]
default() -> Self77     fn default() -> Self {
78         Self {
79             view_mask: 0,
80             color_attachment_formats: Vec::new(),
81             depth_attachment_format: None,
82             stencil_attachment_format: None,
83             _ne: crate::NonExhaustive(()),
84         }
85     }
86 }
87 
88 impl PipelineRenderingCreateInfo {
from_subpass(subpass: &Subpass) -> Self89     pub(crate) fn from_subpass(subpass: &Subpass) -> Self {
90         let subpass_desc = subpass.subpass_desc();
91         let rp_attachments = subpass.render_pass().attachments();
92 
93         Self {
94             view_mask: subpass_desc.view_mask,
95             color_attachment_formats: (subpass_desc.color_attachments.iter())
96                 .map(|atch_ref| {
97                     atch_ref.as_ref().map(|atch_ref| {
98                         rp_attachments[atch_ref.attachment as usize].format.unwrap()
99                     })
100                 })
101                 .collect(),
102             depth_attachment_format: (subpass_desc.depth_stencil_attachment.as_ref())
103                 .map(|atch_ref| rp_attachments[atch_ref.attachment as usize].format.unwrap())
104                 .filter(|format| format.aspects().intersects(ImageAspects::DEPTH)),
105             stencil_attachment_format: (subpass_desc.depth_stencil_attachment.as_ref())
106                 .map(|atch_ref| rp_attachments[atch_ref.attachment as usize].format.unwrap())
107                 .filter(|format| format.aspects().intersects(ImageAspects::STENCIL)),
108             _ne: crate::NonExhaustive(()),
109         }
110     }
111 
from_rendering_info(info: &RenderingInfo) -> Self112     pub(crate) fn from_rendering_info(info: &RenderingInfo) -> Self {
113         Self {
114             view_mask: info.view_mask,
115             color_attachment_formats: (info.color_attachments.iter())
116                 .map(|atch_info| {
117                     atch_info
118                         .as_ref()
119                         .map(|atch_info| atch_info.image_view.format().unwrap())
120                 })
121                 .collect(),
122             depth_attachment_format: (info.depth_attachment.as_ref())
123                 .map(|atch_info| atch_info.image_view.format().unwrap()),
124             stencil_attachment_format: (info.stencil_attachment.as_ref())
125                 .map(|atch_info| atch_info.image_view.format().unwrap()),
126             _ne: crate::NonExhaustive(()),
127         }
128     }
129 
from_inheritance_rendering_info( info: &CommandBufferInheritanceRenderingInfo, ) -> Self130     pub(crate) fn from_inheritance_rendering_info(
131         info: &CommandBufferInheritanceRenderingInfo,
132     ) -> Self {
133         Self {
134             view_mask: info.view_mask,
135             color_attachment_formats: info.color_attachment_formats.clone(),
136             depth_attachment_format: info.depth_attachment_format,
137             stencil_attachment_format: info.stencil_attachment_format,
138             _ne: crate::NonExhaustive(()),
139         }
140     }
141 }
142