rotex-vulkan 0.1.0

A Vulkan backend for rotex_core
Documentation
use ash::vk;

use super::device::Device;
use crate::error::vk_error;

pub struct Framebuffer {
    pub(crate) framebuffer: vk::Framebuffer,
    pub(crate) extent: vk::Extent2D,
}

impl Framebuffer {
    pub fn handle(&self) -> vk::Framebuffer {
        self.framebuffer
    }

    pub fn extent(&self) -> vk::Extent2D {
        self.extent
    }

    pub fn destroy(&self, device: &Device) {
        unsafe {
            device
                .logical_device()
                .destroy_framebuffer(self.framebuffer, None);
        }
    }
}

pub struct FramebufferBuilder {
    attachments: Vec<vk::ImageView>,
    width: u32,
    height: u32,
    layers: u32,
    flags: vk::FramebufferCreateFlags,
}

impl FramebufferBuilder {
    pub fn new() -> Self {
        Self {
            attachments: Vec::new(),
            width: 0,
            height: 0,
            layers: 1,
            flags: vk::FramebufferCreateFlags::empty(),
        }
    }

    pub fn with_attachment(mut self, attachment: vk::ImageView) -> Self {
        self.attachments.push(attachment);
        self
    }

    pub fn with_extent(mut self, width: u32, height: u32) -> Self {
        self.width = width;
        self.height = height;
        self
    }

    pub fn with_layers(mut self, layers: u32) -> Self {
        self.layers = layers;
        self
    }

    pub fn with_flags(mut self, flags: vk::FramebufferCreateFlags) -> Self {
        self.flags |= flags;
        self
    }

    pub fn build(
        self,
        device: &Device,
        render_pass: vk::RenderPass,
    ) -> Result<Framebuffer, crate::Error> {
        debug_assert!(
            self.width > 0 && self.height > 0,
            "Rotex Core Panic: Framebuffer dimensions must be greater than zero!"
        );
        if !self.flags.contains(vk::FramebufferCreateFlags::IMAGELESS) {
            debug_assert!(
                !self.attachments.is_empty(),
                "Rotex Core Panic: Standard framebuffers require at least one attachment view!"
            );
        }

        let framebuffer_info = vk::FramebufferCreateInfo::default()
            .render_pass(render_pass)
            .attachments(&self.attachments)
            .width(self.width)
            .height(self.height)
            .layers(self.layers)
            .flags(self.flags);

        let framebuffer = unsafe {
            device
                .logical_device()
                .create_framebuffer(&framebuffer_info, None)
        }
        .map_err(vk_error)?;

        Ok(Framebuffer {
            framebuffer,
            extent: vk::Extent2D {
                width: self.width,
                height: self.height,
            },
        })
    }
}