bedrock/renderpass/
standard.rs

1use crate::ffi_helper::slice_as_ptr_empty_null;
2use crate::*;
3
4impl VkAttachmentDescription {
5    pub const fn new(format: VkFormat, init_layout: ImageLayout, fin_layout: ImageLayout) -> Self {
6        Self {
7            format,
8            samples: 1,
9            loadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE,
10            storeOp: VK_ATTACHMENT_STORE_OP_DONT_CARE,
11            stencilLoadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE,
12            stencilStoreOp: VK_ATTACHMENT_STORE_OP_DONT_CARE,
13            initialLayout: init_layout as _,
14            finalLayout: fin_layout as _,
15            flags: 0,
16        }
17    }
18
19    pub const fn format(self, fmt: VkFormat) -> Self {
20        Self { format: fmt, ..self }
21    }
22
23    /// default: don't care
24    pub const fn load_op(self, op: LoadOp) -> Self {
25        Self {
26            loadOp: op as _,
27            ..self
28        }
29    }
30    /// default: don't care
31    pub const fn store_op(self, op: StoreOp) -> Self {
32        Self {
33            storeOp: op as _,
34            ..self
35        }
36    }
37    pub const fn color_memory_op(self, load: LoadOp, store: StoreOp) -> Self {
38        self.load_op(load).store_op(store)
39    }
40
41    /// default: don't care
42    pub const fn stencil_load_op(self, op: LoadOp) -> Self {
43        Self {
44            stencilLoadOp: op as _,
45            ..self
46        }
47    }
48    /// default: don't care
49    pub const fn stencil_store_op(self, op: StoreOp) -> Self {
50        Self {
51            stencilStoreOp: op as _,
52            ..self
53        }
54    }
55    pub const fn stencil_memory_op(self, load: LoadOp, store: StoreOp) -> Self {
56        self.stencil_load_op(load).stencil_store_op(store)
57    }
58
59    pub const fn init_layout(self, layout: ImageLayout) -> Self {
60        Self {
61            initialLayout: layout as _,
62            ..self
63        }
64    }
65    pub const fn fin_layout(self, layout: ImageLayout) -> Self {
66        Self {
67            finalLayout: layout as _,
68            ..self
69        }
70    }
71    pub const fn image_layout_transition(self, init_layout: ImageLayout, fin_layout: ImageLayout) -> Self {
72        self.init_layout(init_layout).fin_layout(fin_layout)
73    }
74    pub const fn with_layout_from(self, trans: LayoutTransition) -> Self {
75        self.init_layout(trans.from).fin_layout(trans.to)
76    }
77
78    pub const fn may_alias(mut self) -> Self {
79        self.flags |= VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
80        self
81    }
82    pub const fn no_alias(mut self) -> Self {
83        self.flags &= !VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
84        self
85    }
86    pub const fn samples(self, count: u32) -> Self {
87        Self { samples: count, ..self }
88    }
89}
90
91impl VkAttachmentReference {
92    pub const UNUSED: Self = Self {
93        attachment: VK_ATTACHMENT_UNUSED,
94        layout: 0,
95    };
96
97    pub const fn new(attachment_index: u32, layout: ImageLayout) -> Self {
98        Self {
99            attachment: attachment_index,
100            layout: layout as _,
101        }
102    }
103}
104
105/// Builder structure to construct the `VkSubpassDescription`
106///
107/// ## The `layout` parameter of each attachment
108///
109/// The `layout` parameter describes what layout the attachment will be in during the subpass.
110///
111/// ## How *input attachments* work
112///
113/// * Each element of the array corresponds to an input attachment unit number in the shader.
114///   * i. e. if the shader declares an input variable `layout(input_attachment_index=X, set=Y, binding=Z)`
115///     then it uses the attachment provided in `input_attachments[X]`.
116/// * Input attachments *must* also be bound to the pipeline with a descriptor set, with the input attachment descriptor
117///   written in the location (set=Y, binding=Z).
118/// * Fragment shaders *can* use subpass input variables to access the contents of an input attachment at the fragment's
119///   (x, y, layer) framebuffer coordinates.
120///
121#[repr(transparent)]
122#[derive(Clone)]
123pub struct SubpassDescription<'r> {
124    base: VkSubpassDescription,
125    input_lifetime: core::marker::PhantomData<&'r [VkAttachmentReference]>,
126    color_lifetime: core::marker::PhantomData<&'r [VkAttachmentReference]>,
127    resolve_lifetime: core::marker::PhantomData<&'r [VkAttachmentReference]>,
128    depth_stencil_lifetime: core::marker::PhantomData<Option<&'r VkAttachmentReference>>,
129    preserve_lifetime: core::marker::PhantomData<&'r [u32]>,
130}
131impl<'r> SubpassDescription<'r> {
132    pub const fn new() -> Self {
133        Self {
134            base: VkSubpassDescription {
135                pipelineBindPoint: VK_PIPELINE_BIND_POINT_GRAPHICS,
136                flags: 0,
137                inputAttachmentCount: 0,
138                pInputAttachments: core::ptr::null(),
139                colorAttachmentCount: 0,
140                pColorAttachments: core::ptr::null(),
141                pResolveAttachments: core::ptr::null(),
142                pDepthStencilAttachment: core::ptr::null(),
143                preserveAttachmentCount: 0,
144                pPreserveAttachments: core::ptr::null(),
145            },
146            input_lifetime: core::marker::PhantomData,
147            color_lifetime: core::marker::PhantomData,
148            resolve_lifetime: core::marker::PhantomData,
149            depth_stencil_lifetime: core::marker::PhantomData,
150            preserve_lifetime: core::marker::PhantomData,
151        }
152    }
153
154    pub const fn input_attachments(mut self, inputs: &'r [VkAttachmentReference]) -> Self {
155        self.base.inputAttachmentCount = inputs.len() as _;
156        self.base.pInputAttachments = slice_as_ptr_empty_null(inputs);
157
158        self
159    }
160
161    pub const fn color_attachments(
162        mut self,
163        colors: &'r [VkAttachmentReference],
164        resolves: &'r [VkAttachmentReference],
165    ) -> Self {
166        assert!(resolves.is_empty() || resolves.len() == colors.len());
167
168        self.base.colorAttachmentCount = colors.len() as _;
169        self.base.pColorAttachments = slice_as_ptr_empty_null(colors);
170        self.base.pResolveAttachments = slice_as_ptr_empty_null(resolves);
171
172        self
173    }
174
175    pub const fn depth_stencil_attachment(mut self, a: &'r VkAttachmentReference) -> Self {
176        self.base.pDepthStencilAttachment = a as *const _ as _;
177
178        self
179    }
180
181    pub const fn preserved_attachments(mut self, a: &'r [u32]) -> Self {
182        self.base.preserveAttachmentCount = a.len() as _;
183        self.base.pPreserveAttachments = if a.is_empty() { core::ptr::null() } else { a.as_ptr() };
184
185        self
186    }
187}
188
189/// Builder structure to construct the `RenderPass`
190#[repr(transparent)]
191#[derive(Clone)]
192pub struct RenderPassCreateInfo<'r> {
193    base: VkRenderPassCreateInfo,
194    attachments: core::marker::PhantomData<&'r [VkAttachmentDescription]>,
195    subpasses: core::marker::PhantomData<&'r [SubpassDescription<'r>]>,
196    dependencies: core::marker::PhantomData<&'r [VkSubpassDependency]>,
197}
198impl<'r> RenderPassCreateInfo<'r> {
199    pub const fn new(
200        attachments: &'r [VkAttachmentDescription],
201        subpasses: &'r [SubpassDescription<'r>],
202        dependencies: &'r [VkSubpassDependency],
203    ) -> Self {
204        Self {
205            base: VkRenderPassCreateInfo {
206                sType: VkRenderPassCreateInfo::TYPE,
207                pNext: core::ptr::null(),
208                flags: 0,
209                attachmentCount: attachments.len() as _,
210                pAttachments: slice_as_ptr_empty_null(attachments) as _,
211                subpassCount: subpasses.len() as _,
212                pSubpasses: slice_as_ptr_empty_null(subpasses) as _,
213                dependencyCount: dependencies.len() as _,
214                pDependencies: slice_as_ptr_empty_null(dependencies) as _,
215            },
216            attachments: core::marker::PhantomData,
217            subpasses: core::marker::PhantomData,
218            dependencies: core::marker::PhantomData,
219        }
220    }
221
222    pub const unsafe fn from_raw(raw: VkRenderPassCreateInfo) -> Self {
223        Self {
224            base: raw,
225            attachments: core::marker::PhantomData,
226            subpasses: core::marker::PhantomData,
227            dependencies: core::marker::PhantomData,
228        }
229    }
230
231    pub const fn into_raw(self) -> VkRenderPassCreateInfo {
232        self.base
233    }
234}
235#[implements]
236impl super::AnyRenderPassCreateInfo for RenderPassCreateInfo<'_> {
237    fn execute(
238        &self,
239        device: &(impl crate::Device + ?Sized),
240        allocation_callbacks: Option<&VkAllocationCallbacks>,
241    ) -> crate::Result<VkRenderPass> {
242        device.new_render_pass(self, allocation_callbacks)
243    }
244}