Skip to main content

bedrock/
framebuffer.rs

1//! Vulkan Framebuffer
2use bedrock_vk::{self as brvk, TypedVulkanStructure, VkRawHandle};
3
4use crate::ffi_helper::slice_as_ptr_empty_null;
5use crate::*;
6use core::ops::*;
7use derives::implements;
8
9/// Opaque handle to a framebuffer object
10#[derive(VkHandle, VkObject)]
11#[VkObject(type = brvk::VkFramebuffer::OBJECT_TYPE)]
12pub struct FramebufferObject<'r, Device: VkHandle<Handle = brvk::VkDevice>> {
13    #[handle]
14    pub(crate) handle: brvk::VkFramebuffer,
15    pub(crate) parent: Device,
16    pub(crate) _under_resources:
17        core::marker::PhantomData<&'r [Box<dyn crate::VkHandle<Handle = brvk::VkImageView> + 'r>]>,
18}
19#[implements]
20impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for FramebufferObject<'_, Device> {
21    #[inline(always)]
22    fn drop(&mut self) {
23        unsafe {
24            crate::vkfn_wrapper::destroy_framebuffer(
25                self.parent.as_transparent_ref(),
26                VkHandleRefMut::dangling(self.handle),
27                None,
28            );
29        }
30    }
31}
32unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for FramebufferObject<'_, Device> {}
33unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for FramebufferObject<'_, Device> {}
34impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for FramebufferObject<'_, Device> {
35    #[inline(always)]
36    fn device_handle(&self) -> brvk::VkDevice {
37        self.parent.native_ptr()
38    }
39}
40impl<Device: crate::Device> DeviceChild for FramebufferObject<'_, Device> {
41    type ConcreteDevice = Device;
42
43    #[inline(always)]
44    fn device(&self) -> &Self::ConcreteDevice {
45        &self.parent
46    }
47}
48impl<Device: VkHandle<Handle = brvk::VkDevice>> Framebuffer for FramebufferObject<'_, Device> {}
49impl<Device: VkHandle<Handle = brvk::VkDevice>> FramebufferObject<'_, Device> {
50    /// Constructs from raw values
51    /// # Safety
52    /// the resource must be created from the device and not freed anywhere
53    pub const unsafe fn manage(handle: brvk::VkFramebuffer, parent: Device) -> Self {
54        Self {
55            handle,
56            parent,
57            _under_resources: core::marker::PhantomData,
58        }
59    }
60
61    /// Purges the construct (Drop will not be called for this resource)
62    pub const fn unmanage(self) -> (brvk::VkFramebuffer, Device) {
63        let h = self.handle;
64        let p = unsafe { core::ptr::read(&self.parent) };
65        core::mem::forget(self);
66
67        (h, p)
68    }
69}
70impl<'r, Device: VkHandle<Handle = brvk::VkDevice> + Clone> FramebufferObject<'r, &'_ Device> {
71    /// Owning parent object by cloning it.
72    #[inline(always)]
73    pub fn clone_parent(self) -> FramebufferObject<'r, Device> {
74        let r = FramebufferObject {
75            handle: self.handle,
76            parent: self.parent.clone(),
77            _under_resources: self._under_resources,
78        };
79        core::mem::forget(self);
80
81        r
82    }
83}
84impl<'r, Device: crate::Device> FramebufferObject<'r, Device> {
85    /// Create a new framebuffer object
86    /// # Failures
87    /// On failure, this command returns
88    ///
89    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
90    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
91    #[implements]
92    #[inline]
93    pub fn new(device: Device, info: &FramebufferCreateInfo) -> crate::Result<Self> {
94        Ok(unsafe { Self::manage(device.new_framebuffer_raw(info, None)?, device) })
95    }
96}
97
98#[repr(transparent)]
99#[derive(Clone)]
100pub struct FramebufferCreateInfo<'r, 'rs>(
101    brvk::VkFramebufferCreateInfo,
102    #[allow(clippy::type_complexity)]
103    core::marker::PhantomData<(
104        &'r dyn VkHandle<Handle = brvk::VkRenderPass>,
105        &'rs [&'r dyn VkHandle<Handle = brvk::VkImageView>],
106    )>,
107);
108impl<'r, 'rs> FramebufferCreateInfo<'r, 'rs> {
109    #[inline(always)]
110    pub fn new(
111        render_pass: &'r (impl VkHandle<Handle = brvk::VkRenderPass> + ?Sized),
112        attachments: &'rs [VkHandleRef<'r, brvk::VkImageView>],
113        width: u32,
114        height: u32,
115    ) -> Self {
116        Self(
117            brvk::VkFramebufferCreateInfo {
118                sType: brvk::VkFramebufferCreateInfo::TYPE,
119                pNext: core::ptr::null(),
120                renderPass: render_pass.native_ptr(),
121                flags: 0,
122                attachmentCount: attachments.len() as _,
123                pAttachments: slice_as_ptr_empty_null(attachments) as *const _,
124                width,
125                height,
126                layers: 1,
127            },
128            core::marker::PhantomData,
129        )
130    }
131
132    /// # Safety
133    ///
134    /// raw must be a valid VkFramebufferCreateInfo struct.
135    pub const unsafe fn from_raw(raw: brvk::VkFramebufferCreateInfo) -> Self {
136        Self(raw, core::marker::PhantomData)
137    }
138
139    pub const fn into_raw(self) -> brvk::VkFramebufferCreateInfo {
140        self.0
141    }
142
143    pub const fn with_layers(mut self, layers: u32) -> Self {
144        self.0.layers = layers;
145        self
146    }
147}
148
149pub trait Framebuffer: VkHandle<Handle = brvk::VkFramebuffer> {}
150DerefContainerBracketImpl!(for Framebuffer {});
151GuardsImpl!(for Framebuffer {});