bedrock/renderpass/
mod.rs

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