1use bedrock_vk::{self as brvk, TypedVulkanStructure};
2
3use crate::ffi_helper::slice_as_ptr_empty_null;
4use crate::*;
5
6#[repr(transparent)]
7pub struct AttachmentDescription(brvk::VkAttachmentDescription);
8impl AttachmentDescription {
9 pub const fn new(format: brvk::VkFormat, init_layout: ImageLayout, fin_layout: ImageLayout) -> Self {
10 Self(brvk::VkAttachmentDescription {
11 format,
12 samples: 1,
13 loadOp: brvk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
14 storeOp: brvk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
15 stencilLoadOp: brvk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
16 stencilStoreOp: brvk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
17 initialLayout: init_layout as _,
18 finalLayout: fin_layout as _,
19 flags: 0,
20 })
21 }
22
23 pub const fn format(mut self, fmt: brvk::VkFormat) -> Self {
24 self.0.format = fmt;
25 self
26 }
27
28 pub const fn load_op(mut self, op: LoadOp) -> Self {
30 self.0.loadOp = op as _;
31 self
32 }
33 pub const fn store_op(mut self, op: StoreOp) -> Self {
35 self.0.storeOp = op as _;
36 self
37 }
38 pub const fn color_memory_op(self, load: LoadOp, store: StoreOp) -> Self {
39 self.load_op(load).store_op(store)
40 }
41
42 pub const fn stencil_load_op(mut self, op: LoadOp) -> Self {
44 self.0.stencilLoadOp = op as _;
45 self
46 }
47 pub const fn stencil_store_op(mut self, op: StoreOp) -> Self {
49 self.0.stencilStoreOp = op as _;
50 self
51 }
52 pub const fn stencil_memory_op(self, load: LoadOp, store: StoreOp) -> Self {
53 self.stencil_load_op(load).stencil_store_op(store)
54 }
55
56 pub const fn init_layout(mut self, layout: ImageLayout) -> Self {
57 self.0.initialLayout = layout as _;
58 self
59 }
60 pub const fn fin_layout(mut self, layout: ImageLayout) -> Self {
61 self.0.finalLayout = layout as _;
62 self
63 }
64 pub const fn image_layout_transition(self, init_layout: ImageLayout, fin_layout: ImageLayout) -> Self {
65 self.init_layout(init_layout).fin_layout(fin_layout)
66 }
67 pub const fn with_layout_from(self, trans: LayoutTransition) -> Self {
68 self.init_layout(trans.from).fin_layout(trans.to)
69 }
70
71 pub const fn may_alias(mut self) -> Self {
72 self.0.flags |= brvk::VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
73 self
74 }
75 pub const fn no_alias(mut self) -> Self {
76 self.0.flags &= !brvk::VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
77 self
78 }
79 pub const fn samples(mut self, count: u32) -> Self {
80 self.0.samples = count;
81 self
82 }
83}
84
85#[repr(transparent)]
86pub struct AttachmentReference(pub brvk::VkAttachmentReference);
87impl AttachmentReference {
88 pub const UNUSED: Self = Self(brvk::VkAttachmentReference {
89 attachment: brvk::VK_ATTACHMENT_UNUSED,
90 layout: 0,
91 });
92
93 pub const fn new(attachment_index: u32, layout: ImageLayout) -> Self {
94 Self(brvk::VkAttachmentReference {
95 attachment: attachment_index,
96 layout: layout as _,
97 })
98 }
99}
100
101#[repr(transparent)]
118#[derive(Clone)]
119pub struct SubpassDescription<'r> {
120 base: brvk::VkSubpassDescription,
121 input_lifetime: core::marker::PhantomData<&'r [AttachmentReference]>,
122 color_lifetime: core::marker::PhantomData<&'r [AttachmentReference]>,
123 resolve_lifetime: core::marker::PhantomData<&'r [AttachmentReference]>,
124 depth_stencil_lifetime: core::marker::PhantomData<Option<&'r AttachmentReference>>,
125 preserve_lifetime: core::marker::PhantomData<&'r [u32]>,
126}
127impl<'r> SubpassDescription<'r> {
128 pub const fn new() -> Self {
129 Self {
130 base: brvk::VkSubpassDescription {
131 pipelineBindPoint: brvk::VK_PIPELINE_BIND_POINT_GRAPHICS,
132 flags: 0,
133 inputAttachmentCount: 0,
134 pInputAttachments: core::ptr::null(),
135 colorAttachmentCount: 0,
136 pColorAttachments: core::ptr::null(),
137 pResolveAttachments: core::ptr::null(),
138 pDepthStencilAttachment: core::ptr::null(),
139 preserveAttachmentCount: 0,
140 pPreserveAttachments: core::ptr::null(),
141 },
142 input_lifetime: core::marker::PhantomData,
143 color_lifetime: core::marker::PhantomData,
144 resolve_lifetime: core::marker::PhantomData,
145 depth_stencil_lifetime: core::marker::PhantomData,
146 preserve_lifetime: core::marker::PhantomData,
147 }
148 }
149
150 pub const fn input_attachments(mut self, inputs: &'r [AttachmentReference]) -> Self {
151 self.base.inputAttachmentCount = inputs.len() as _;
152 self.base.pInputAttachments = slice_as_ptr_empty_null(inputs).cast();
153
154 self
155 }
156
157 pub const fn color_attachments(
158 mut self,
159 colors: &'r [AttachmentReference],
160 resolves: &'r [AttachmentReference],
161 ) -> Self {
162 assert!(resolves.is_empty() || resolves.len() == colors.len());
163
164 self.base.colorAttachmentCount = colors.len() as _;
165 self.base.pColorAttachments = slice_as_ptr_empty_null(colors).cast();
166 self.base.pResolveAttachments = slice_as_ptr_empty_null(resolves).cast();
167
168 self
169 }
170
171 pub const fn depth_stencil_attachment(mut self, a: &'r AttachmentReference) -> Self {
172 self.base.pDepthStencilAttachment = core::ptr::from_ref(a).cast();
173
174 self
175 }
176
177 pub const fn preserved_attachments(mut self, a: &'r [u32]) -> Self {
178 self.base.preserveAttachmentCount = a.len() as _;
179 self.base.pPreserveAttachments = if a.is_empty() { core::ptr::null() } else { a.as_ptr() };
180
181 self
182 }
183}
184
185#[repr(transparent)]
187#[derive(Clone)]
188pub struct RenderPassCreateInfo<'r> {
189 base: brvk::VkRenderPassCreateInfo,
190 attachments: core::marker::PhantomData<&'r [AttachmentDescription]>,
191 subpasses: core::marker::PhantomData<&'r [SubpassDescription<'r>]>,
192 dependencies: core::marker::PhantomData<&'r [brvk::VkSubpassDependency]>,
193}
194impl<'r> RenderPassCreateInfo<'r> {
195 pub const fn new(
196 attachments: &'r [AttachmentDescription],
197 subpasses: &'r [SubpassDescription<'r>],
198 dependencies: &'r [brvk::VkSubpassDependency],
199 ) -> Self {
200 Self {
201 base: brvk::VkRenderPassCreateInfo {
202 sType: brvk::VkRenderPassCreateInfo::TYPE,
203 pNext: core::ptr::null(),
204 flags: 0,
205 attachmentCount: attachments.len() as _,
206 pAttachments: slice_as_ptr_empty_null(attachments).cast(),
207 subpassCount: subpasses.len() as _,
208 pSubpasses: slice_as_ptr_empty_null(subpasses).cast(),
209 dependencyCount: dependencies.len() as _,
210 pDependencies: slice_as_ptr_empty_null(dependencies) as _,
211 },
212 attachments: core::marker::PhantomData,
213 subpasses: core::marker::PhantomData,
214 dependencies: core::marker::PhantomData,
215 }
216 }
217
218 pub const unsafe fn from_raw(raw: brvk::VkRenderPassCreateInfo) -> Self {
222 Self {
223 base: raw,
224 attachments: core::marker::PhantomData,
225 subpasses: core::marker::PhantomData,
226 dependencies: core::marker::PhantomData,
227 }
228 }
229
230 pub const fn into_raw(self) -> brvk::VkRenderPassCreateInfo {
231 self.base
232 }
233}
234#[implements]
235impl super::AnyRenderPassCreateInfo for RenderPassCreateInfo<'_> {
236 fn execute(
237 &self,
238 device: &(impl crate::Device + ?Sized),
239 allocation_callbacks: Option<&brvk::VkAllocationCallbacks>,
240 ) -> crate::Result<brvk::VkRenderPass> {
241 device.new_render_pass(self, allocation_callbacks)
242 }
243}