1use crate::{
2 render_pass::RenderPass, Device, DeviceOwned, ImageDimensions, ImageViewAccess,
3 ALLOCATION_CALLBACK_NONE,
4};
5use ash::{
6 prelude::VkResult,
7 vk::{self, Handle},
8};
9use std::sync::Arc;
10
11pub struct Framebuffer {
12 handle: vk::Framebuffer,
13 properties: FramebufferProperties,
14
15 render_pass: Arc<RenderPass>,
17}
18
19impl Framebuffer {
20 pub fn new(render_pass: Arc<RenderPass>, properties: FramebufferProperties) -> VkResult<Self> {
21 let vk_attachment_image_view_handles = properties.vk_attachment_image_view_handles();
22 let create_info_builder = properties.write_create_info_builder(
23 vk::FramebufferCreateInfo::builder(),
24 &vk_attachment_image_view_handles,
25 &render_pass,
26 );
27
28 let handle = unsafe {
29 render_pass
30 .device()
31 .inner()
32 .create_framebuffer(&create_info_builder, ALLOCATION_CALLBACK_NONE)
33 }?;
34
35 Ok(Self {
36 handle,
37 properties,
38 render_pass,
39 })
40 }
41
42 pub unsafe fn new_from_create_info(
45 render_pass: Arc<RenderPass>,
46 create_info_builder: vk::FramebufferCreateInfoBuilder,
47 ) -> VkResult<Self> {
48 let properties = FramebufferProperties::from_create_info_builder(&create_info_builder);
49
50 let handle = unsafe {
51 render_pass
52 .device()
53 .inner()
54 .create_framebuffer(&create_info_builder, ALLOCATION_CALLBACK_NONE)
55 }?;
56
57 Ok(Self {
58 handle,
59 properties,
60 render_pass,
61 })
62 }
63
64 pub fn whole_rect(&self) -> vk::Rect2D {
65 vk::Rect2D {
66 extent: vk::Extent2D {
67 width: self.properties.dimensions.width(),
68 height: self.properties.dimensions.height(),
69 },
70 offset: vk::Offset2D { x: 0, y: 0 },
71 }
72 }
73
74 pub fn whole_viewport(&self) -> vk::Viewport {
75 self.properties.dimensions.whole_viewport()
76 }
77
78 #[inline]
81 pub fn handle(&self) -> vk::Framebuffer {
82 self.handle
83 }
84
85 #[inline]
86 pub fn properties(&self) -> &FramebufferProperties {
87 &self.properties
88 }
89}
90
91impl DeviceOwned for Framebuffer {
92 #[inline]
93 fn device(&self) -> &Arc<Device> {
94 &self.render_pass.device()
95 }
96
97 #[inline]
98 fn handle_raw(&self) -> u64 {
99 self.handle.as_raw()
100 }
101}
102
103impl Drop for Framebuffer {
104 fn drop(&mut self) {
105 unsafe {
106 self.device()
107 .inner()
108 .destroy_framebuffer(self.handle, ALLOCATION_CALLBACK_NONE);
109 }
110 }
111}
112
113#[derive(Clone, Default)]
115pub struct FramebufferProperties {
116 pub flags: vk::FramebufferCreateFlags,
117 pub attachments: Vec<Arc<dyn ImageViewAccess>>,
118 pub dimensions: ImageDimensions,
119}
120
121impl FramebufferProperties {
122 pub fn new_default(
123 attachments: Vec<Arc<dyn ImageViewAccess>>,
124 dimensions: ImageDimensions,
125 ) -> Self {
126 Self {
127 flags: vk::FramebufferCreateFlags::empty(),
128 attachments,
129 dimensions,
130 }
131 }
132
133 pub fn write_create_info_builder<'a>(
134 &'a self,
135 builder: vk::FramebufferCreateInfoBuilder<'a>,
136 vk_attchment_image_view_handles: &'a [vk::ImageView],
137 render_pass: &RenderPass,
138 ) -> vk::FramebufferCreateInfoBuilder {
139 builder
140 .flags(self.flags)
141 .attachments(vk_attchment_image_view_handles)
142 .height(self.dimensions.height())
143 .width(self.dimensions.width())
144 .layers(self.dimensions.array_layers())
145 .render_pass(render_pass.handle())
146 }
147
148 pub fn vk_attachment_image_view_handles(&self) -> Vec<vk::ImageView> {
149 self.attachments
150 .iter()
151 .map(|image_view| image_view.handle())
152 .collect()
153 }
154
155 pub fn from_create_info_builder(value: &vk::FramebufferCreateInfoBuilder) -> Self {
157 let dimensions = ImageDimensions::new_2d_array(value.width, value.height, value.layers);
158 Self {
159 flags: value.flags,
160 attachments: Vec::new(), dimensions,
162 }
163 }
164}