Skip to main content

rotex_vulkan/backend/vulkan/
framebuffer.rs

1use ash::vk;
2
3use super::device::Device;
4use crate::error::vk_error;
5
6pub struct Framebuffer {
7    pub(crate) framebuffer: vk::Framebuffer,
8    pub(crate) extent: vk::Extent2D,
9}
10
11impl Framebuffer {
12    pub fn handle(&self) -> vk::Framebuffer {
13        self.framebuffer
14    }
15
16    pub fn extent(&self) -> vk::Extent2D {
17        self.extent
18    }
19
20    pub fn destroy(&self, device: &Device) {
21        unsafe {
22            device
23                .logical_device()
24                .destroy_framebuffer(self.framebuffer, None);
25        }
26    }
27}
28
29pub struct FramebufferBuilder {
30    attachments: Vec<vk::ImageView>,
31    width: u32,
32    height: u32,
33    layers: u32,
34    flags: vk::FramebufferCreateFlags,
35}
36
37impl FramebufferBuilder {
38    pub fn new() -> Self {
39        Self {
40            attachments: Vec::new(),
41            width: 0,
42            height: 0,
43            layers: 1,
44            flags: vk::FramebufferCreateFlags::empty(),
45        }
46    }
47
48    pub fn with_attachment(mut self, attachment: vk::ImageView) -> Self {
49        self.attachments.push(attachment);
50        self
51    }
52
53    pub fn with_extent(mut self, width: u32, height: u32) -> Self {
54        self.width = width;
55        self.height = height;
56        self
57    }
58
59    pub fn with_layers(mut self, layers: u32) -> Self {
60        self.layers = layers;
61        self
62    }
63
64    pub fn with_flags(mut self, flags: vk::FramebufferCreateFlags) -> Self {
65        self.flags |= flags;
66        self
67    }
68
69    pub fn build(
70        self,
71        device: &Device,
72        render_pass: vk::RenderPass,
73    ) -> Result<Framebuffer, crate::Error> {
74        debug_assert!(
75            self.width > 0 && self.height > 0,
76            "Rotex Core Panic: Framebuffer dimensions must be greater than zero!"
77        );
78        if !self.flags.contains(vk::FramebufferCreateFlags::IMAGELESS) {
79            debug_assert!(
80                !self.attachments.is_empty(),
81                "Rotex Core Panic: Standard framebuffers require at least one attachment view!"
82            );
83        }
84
85        let framebuffer_info = vk::FramebufferCreateInfo::default()
86            .render_pass(render_pass)
87            .attachments(&self.attachments)
88            .width(self.width)
89            .height(self.height)
90            .layers(self.layers)
91            .flags(self.flags);
92
93        let framebuffer = unsafe {
94            device
95                .logical_device()
96                .create_framebuffer(&framebuffer_info, None)
97        }
98        .map_err(vk_error)?;
99
100        Ok(Framebuffer {
101            framebuffer,
102            extent: vk::Extent2D {
103                width: self.width,
104                height: self.height,
105            },
106        })
107    }
108}