Skip to main content

bedrock/renderpass/
mod.rs

1use bedrock_vk::{self as brvk, TypedVulkanStructure, VkRawHandle};
2
3use crate::ffi_helper::slice_as_ptr_empty_null;
4
5mod standard;
6pub use self::standard::*;
7
8#[cfg(feature = "VK_KHR_create_renderpass2")]
9mod extensible;
10#[cfg(feature = "VK_KHR_create_renderpass2")]
11pub use self::extensible::*;
12
13use crate::*;
14
15pub trait RenderPass: VkHandle<Handle = brvk::VkRenderPass> + DeviceChildHandle {
16    /// Returns the granularity for optimal render area
17    #[implements]
18    fn optimal_granularity(&self) -> brvk::VkExtent2D {
19        let mut e = core::mem::MaybeUninit::uninit();
20        unsafe {
21            brvk::fns::get_render_area_granularity(self.device_handle(), self.native_ptr(), e.as_mut_ptr());
22
23            e.assume_init()
24        }
25    }
26
27    #[inline(always)]
28    fn subpass<'a>(&'a self, index: u32) -> SubpassRef<'a, Self> {
29        SubpassRef(self, index)
30    }
31}
32DerefContainerBracketImpl!(for RenderPass {});
33GuardsImpl!(for RenderPass {});
34
35pub trait ConcreteDeviceRenderPass: RenderPass + DeviceChild {}
36DerefContainerBracketImpl!(for ConcreteDeviceRenderPass {});
37GuardsImpl!(for ConcreteDeviceRenderPass {});
38
39/// Opaque handle to a render pass object
40#[derive(VkHandle, VkObject)]
41#[VkObject(type = brvk::VkRenderPass::OBJECT_TYPE)]
42pub struct RenderPassObject<Device: VkHandle<Handle = brvk::VkDevice>>(
43    pub(crate) brvk::VkRenderPass,
44    pub(crate) Device,
45);
46#[implements]
47impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for RenderPassObject<Device> {
48    #[inline(always)]
49    fn drop(&mut self) {
50        unsafe {
51            crate::vkfn_wrapper::destroy_render_pass(
52                self.1.as_transparent_ref(),
53                VkHandleRefMut::dangling(self.0),
54                None,
55            );
56        }
57    }
58}
59unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for RenderPassObject<Device> {}
60unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for RenderPassObject<Device> {}
61impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for RenderPassObject<Device> {
62    #[inline(always)]
63    fn device_handle(&self) -> brvk::VkDevice {
64        self.1.native_ptr()
65    }
66}
67impl<Device: crate::Device> DeviceChild for RenderPassObject<Device> {
68    type ConcreteDevice = Device;
69
70    #[inline(always)]
71    fn device(&self) -> &Self::ConcreteDevice {
72        &self.1
73    }
74}
75impl<Device: VkHandle<Handle = brvk::VkDevice>> RenderPass for RenderPassObject<Device> {}
76impl<Device: VkHandle<Handle = brvk::VkDevice>> RenderPassObject<Device> {
77    /// Constructs from raw values
78    /// # Safety
79    /// the resource must be created from the parent
80    pub const unsafe fn manage(handle: brvk::VkRenderPass, parent: Device) -> Self {
81        Self(handle, parent)
82    }
83
84    /// Purges internal values (Drop will not be called for this resource)
85    pub const fn unmanage(self) -> (brvk::VkRenderPass, Device) {
86        let v = self.0;
87        let p = unsafe { core::ptr::read(&self.1) };
88        core::mem::forget(self);
89
90        (v, p)
91    }
92}
93impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> RenderPassObject<&'_ Device> {
94    /// Owning parent object by cloning it.
95    #[inline(always)]
96    pub fn clone_parent(self) -> RenderPassObject<Device> {
97        let r = RenderPassObject(self.0, self.1.clone());
98        core::mem::forget(self);
99
100        r
101    }
102}
103impl<Device: crate::Device> RenderPassObject<Device> {
104    #[implements]
105    #[inline(always)]
106    pub fn new(device: Device, create_info: &(impl AnyRenderPassCreateInfo + ?Sized)) -> crate::Result<Self> {
107        create_info.execute(&device, None).map(move |x| Self(x, device))
108    }
109}
110
111#[implements]
112pub trait AnyRenderPassCreateInfo {
113    fn execute(
114        &self,
115        device: &(impl crate::Device + ?Sized),
116        allocation_callbacks: Option<&brvk::VkAllocationCallbacks>,
117    ) -> crate::Result<brvk::VkRenderPass>;
118}
119
120#[repr(transparent)]
121pub struct RenderPassBeginInfo<'d>(
122    brvk::VkRenderPassBeginInfo,
123    #[allow(clippy::type_complexity)]
124    core::marker::PhantomData<(
125        &'d dyn VkHandle<Handle = brvk::VkRenderPass>,
126        &'d dyn VkHandle<Handle = brvk::VkFramebuffer>,
127        &'d [ClearValue],
128    )>,
129);
130impl<'d> RenderPassBeginInfo<'d> {
131    #[inline]
132    pub fn new(
133        render_pass: &'d (impl VkHandle<Handle = brvk::VkRenderPass> + ?Sized),
134        framebuffer: &'d (impl VkHandle<Handle = brvk::VkFramebuffer> + ?Sized),
135        render_area: brvk::VkRect2D,
136        clear_values: &'d [ClearValue],
137    ) -> Self {
138        Self(
139            brvk::VkRenderPassBeginInfo {
140                sType: brvk::VkRenderPassBeginInfo::TYPE,
141                pNext: core::ptr::null(),
142                renderPass: render_pass.native_ptr(),
143                framebuffer: framebuffer.native_ptr(),
144                renderArea: render_area,
145                clearValueCount: clear_values.len() as _,
146                pClearValues: slice_as_ptr_empty_null(clear_values).cast(),
147            },
148            core::marker::PhantomData,
149        )
150    }
151}
152impl<'d> AsRef<brvk::VkRenderPassBeginInfo> for RenderPassBeginInfo<'d> {
153    #[inline(always)]
154    fn as_ref(&self) -> &brvk::VkRenderPassBeginInfo {
155        &self.0
156    }
157}
158
159#[cfg(feature = "VK_KHR_create_renderpass2")]
160#[repr(transparent)]
161pub struct SubpassBeginInfo(brvk::VkSubpassBeginInfoKHR);
162#[cfg(feature = "VK_KHR_create_renderpass2")]
163impl SubpassBeginInfo {
164    pub const fn new(contents: SubpassContents) -> Self {
165        Self(brvk::VkSubpassBeginInfoKHR {
166            sType: brvk::VkSubpassBeginInfoKHR::TYPE,
167            pNext: core::ptr::null(),
168            contents: contents as _,
169        })
170    }
171}
172
173#[cfg(feature = "VK_KHR_create_renderpass2")]
174#[repr(transparent)]
175pub struct SubpassEndInfo(brvk::VkSubpassEndInfoKHR);
176#[cfg(feature = "VK_KHR_create_renderpass2")]
177impl SubpassEndInfo {
178    pub const fn new() -> Self {
179        Self(brvk::VkSubpassEndInfoKHR {
180            sType: brvk::VkSubpassEndInfoKHR::TYPE,
181            pNext: core::ptr::null(),
182        })
183    }
184}
185
186/// A reference to a subpass in a render pass object.
187pub struct SubpassRef<'r, RenderPass: 'r + ?Sized + VkHandle<Handle = brvk::VkRenderPass>>(pub &'r RenderPass, pub u32);
188impl<'r, RenderPass: 'r + ?Sized + VkHandle<Handle = brvk::VkRenderPass>> Clone for SubpassRef<'r, RenderPass> {
189    #[inline(always)]
190    fn clone(&self) -> Self {
191        *self
192    }
193}
194impl<'r, RenderPass: 'r + ?Sized + VkHandle<Handle = brvk::VkRenderPass>> Copy for SubpassRef<'r, RenderPass> {}
195impl<'r, RenderPass: 'r + ?Sized + VkHandle<Handle = brvk::VkRenderPass>> PartialEq for SubpassRef<'r, RenderPass> {
196    #[inline(always)]
197    fn eq(&self, other: &Self) -> bool {
198        core::ptr::eq(self.0, other.0) && self.1 == other.1
199    }
200}
201impl<'r, RenderPass: 'r + ?Sized + VkHandle<Handle = brvk::VkRenderPass>> Eq for SubpassRef<'r, RenderPass> {}
202impl<'r, RenderPass: 'r + ?Sized + VkHandle<Handle = brvk::VkRenderPass>> core::hash::Hash
203    for SubpassRef<'r, RenderPass>
204{
205    #[inline(always)]
206    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
207        (self.0 as *const RenderPass, self.1).hash(state)
208    }
209}
210impl<'r, RenderPass: 'r + ?Sized + VkHandle<Handle = brvk::VkRenderPass>> core::fmt::Debug
211    for SubpassRef<'r, RenderPass>
212{
213    #[inline(always)]
214    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
215        write!(f, "RenderPass({:p}).{}", self.0, self.1)
216    }
217}
218
219#[repr(i32)]
220#[derive(Debug, Clone, Copy, PartialEq, Eq)]
221pub enum LoadOp {
222    /// The previous contents of the image within the render area will be preserved.
223    ///
224    /// ## Used access types
225    ///
226    /// This operation uses the "Read" access
227    Load = brvk::VK_ATTACHMENT_LOAD_OP_LOAD,
228    /// The contents within the render area will be cleared to a uniform value, which is
229    /// specified when a render pass instance is begun.
230    ///
231    /// ## Used access types
232    ///
233    /// This operation uses the "Write" access
234    Clear = brvk::VK_ATTACHMENT_LOAD_OP_CLEAR,
235    /// The previous contents within the area need not be preserved;
236    /// the contents of the attachment will be undefined inside the render area.
237    ///
238    /// ## Used access types
239    ///
240    /// This operation uses the "Write" access
241    DontCare = brvk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
242}
243
244/// Possible argument values of `AttachmentDescription::store_op` and `stencil_store_op`,
245/// specifying how the contents of the attachment are treated.
246///
247/// ## Used access types
248///
249/// Both items use the "Write" access
250#[repr(i32)]
251#[derive(Debug, Clone, Copy, PartialEq, Eq)]
252pub enum StoreOp {
253    /// The contents generated during the render pass and within the render area are written to memory.
254    Store = brvk::VK_ATTACHMENT_STORE_OP_STORE,
255    /// The contents within the render area are not needed after rendering, and *may* be discarded;
256    /// the contents of the attachment will be undefined inside the render area.
257    DontCare = brvk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
258}