vulkan_lib/vulkan-rs/src/framebuffer.rs

146 lines
3.3 KiB
Rust
Raw Normal View History

2023-01-14 12:03:01 +00:00
use crate::prelude::*;
use anyhow::Result;
use std::sync::Arc;
pub struct FramebufferBuilder<'a> {
render_pass: Option<&'a Arc<RenderPass>>,
attachments: Vec<&'a Arc<Image>>,
width: u32,
height: u32,
layers: u32,
}
impl<'a> FramebufferBuilder<'a> {
pub fn set_render_pass(mut self, render_pass: &'a Arc<RenderPass>) -> Self {
self.render_pass = Some(render_pass);
self
}
pub fn add_attachment(mut self, image: &'a Arc<Image>) -> Self {
self.attachments.push(image);
self
}
pub fn set_width(mut self, width: u32) -> Self {
self.width = width;
self
}
pub fn set_height(mut self, height: u32) -> Self {
self.height = height;
self
}
pub fn set_layer_count(mut self, layers: u32) -> Self {
self.layers = layers;
self
}
pub fn build(mut self, device: Arc<Device>) -> Result<Arc<Framebuffer>> {
if self.attachments.is_empty() {
panic!("no attachments added!");
}
// if width or height are not set, use first attachment as reference
// may not work, if images have different sizes
if self.width == 0 || self.height == 0 {
self.width = self.attachments[0].width();
self.height = self.attachments[0].height();
}
let mut image_views = Vec::with_capacity(self.attachments.len());
let mut images = Vec::with_capacity(self.attachments.len());
for attachment in self.attachments {
image_views.push(attachment.vk_handle());
images.push(attachment.clone());
}
let framebuffer_ci = VkFramebufferCreateInfo::new(
VK_FRAMEBUFFER_CREATE_NULL_BIT,
match self.render_pass {
Some(render_pass) => render_pass.vk_handle(),
None => panic!("no render pass set!"),
},
&image_views,
self.width,
self.height,
self.layers,
);
let framebuffer = device.create_framebuffer(&framebuffer_ci)?;
Ok(Arc::new(Framebuffer {
device,
framebuffer,
images,
width: self.width,
height: self.height,
}))
}
}
#[derive(Debug)]
pub struct Framebuffer {
device: Arc<Device>,
framebuffer: VkFramebuffer,
images: Vec<Arc<Image>>,
width: u32,
height: u32,
}
impl Framebuffer {
pub fn builder<'a>() -> FramebufferBuilder<'a> {
FramebufferBuilder {
render_pass: None,
attachments: Vec::new(),
width: 0,
height: 0,
layers: 1,
}
}
pub fn width(&self) -> u32 {
self.width
}
pub fn height(&self) -> u32 {
self.height
}
pub fn attachments(&self) -> &[Arc<Image>] {
&self.images
}
pub fn image(&self, index: usize) -> &Arc<Image> {
&self.images[index]
}
pub fn image_count(&self) -> usize {
self.images.len()
}
}
impl VulkanDevice for Framebuffer {
fn device(&self) -> &Arc<Device> {
&self.device
}
}
impl_vk_handle!(Framebuffer, VkFramebuffer, framebuffer);
impl Drop for Framebuffer {
fn drop(&mut self) {
self.device.destroy_framebuffer(self.framebuffer);
}
}