mepeyew 0.3.5

mepeyew - Small But Powerful Graphics Library
Documentation
use super::*;

impl VkContext {
    pub fn new_attachment_image(
        &mut self,
        initial_width: usize,
        initial_height: usize,
        attachment_usage: AttachmentImageUsage,
        ext: Option<NewAttachmentImageExt>,
    ) -> GResult<AttachmentImageId> {
        let attachment_image = VkAttachmentImage::new(
            &self.core.dev,
            &self.drop_queue,
            &mut self.alloc,
            initial_width,
            initial_height,
            attachment_usage,
            ext.unwrap_or_default(),
        )?;
        self.attachment_images.push(attachment_image);

        Ok(AttachmentImageId::from_id(self.attachment_images.len() - 1))
    }
}

pub struct VkAttachmentImage {
    ext: NewAttachmentImageExt,

    pub image: VkImage,
    pub format: vk::Format,
    pub image_view: vk::ImageView,
    pub attachment_usage: AttachmentImageUsage,

    drop_queue_ref: VkDropQueueRef,
}

impl VkAttachmentImage {
    pub fn new(
        dev: &Device,
        drop_queue_ref: &VkDropQueueRef,
        alloc: &mut Allocator,
        width: usize,
        height: usize,
        attachment_usage: AttachmentImageUsage,
        ext: NewAttachmentImageExt,
    ) -> GResult<Self> {
        let format = match attachment_usage {
            AttachmentImageUsage::ColorAttachment => ext
                .color_format
                .map(|color_format| match color_format {
                    AttachmentImageColorFormat::R8UNorm => vk::Format::R8G8_UNORM,
                    AttachmentImageColorFormat::R8G8UNorm => vk::Format::R8G8_UNORM,
                    AttachmentImageColorFormat::R8G8B8A8UNorm => vk::Format::R8G8B8A8_UNORM,
                    AttachmentImageColorFormat::R32SFloat => vk::Format::R32_SFLOAT,
                    AttachmentImageColorFormat::R32G32SFloat => vk::Format::R32G32_SFLOAT,
                    AttachmentImageColorFormat::R32G32B32A32SFloat => {
                        vk::Format::R32G32B32A32_SFLOAT
                    }
                })
                .unwrap_or(VK_COLOR_ATTACHMENT_FORMAT),
            AttachmentImageUsage::DepthAttachment => VK_DEPTH_ATTACHMENT_FORMAT,
        };
        let usages = vk::ImageUsageFlags::INPUT_ATTACHMENT
            | match attachment_usage {
                AttachmentImageUsage::ColorAttachment => vk::ImageUsageFlags::COLOR_ATTACHMENT,
                AttachmentImageUsage::DepthAttachment => {
                    vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT
                }
            };
        let aspect = match attachment_usage {
            AttachmentImageUsage::ColorAttachment => vk::ImageAspectFlags::COLOR,
            AttachmentImageUsage::DepthAttachment => vk::ImageAspectFlags::DEPTH,
        };

        let image = VkImage::new(
            dev,
            drop_queue_ref,
            alloc,
            format,
            usages,
            aspect,
            match ext.msaa_samples.unwrap_or_default() {
                MsaaSampleCount::Sample1 => vk::SampleCountFlags::TYPE_1,
                MsaaSampleCount::Sample2 => vk::SampleCountFlags::TYPE_2,
                MsaaSampleCount::Sample4 => vk::SampleCountFlags::TYPE_4,
                MsaaSampleCount::Sample8 => vk::SampleCountFlags::TYPE_8,
                MsaaSampleCount::Sample16 => vk::SampleCountFlags::TYPE_16,
                MsaaSampleCount::Sample32 => vk::SampleCountFlags::TYPE_32,
                MsaaSampleCount::Sample64 => vk::SampleCountFlags::TYPE_64,
            },
            1,
            false,
            vk::Extent3D {
                width: width as u32,
                height: height as u32,
                depth: 1,
            },
        )?;

        let image_view = new_image_view(dev, image.image, format, aspect, 1, false)?;

        Ok(VkAttachmentImage {
            ext,
            attachment_usage,
            format,
            image,
            image_view,
            drop_queue_ref: Arc::clone(drop_queue_ref),
        })
    }

    pub fn resize(
        &mut self,
        dev: &Device,
        drop_queue_ref: &VkDropQueueRef,
        alloc: &mut Allocator,
        width: usize,
        height: usize,
    ) -> GResult<()> {
        let new_attachment_image = VkAttachmentImage::new(
            dev,
            drop_queue_ref,
            alloc,
            width,
            height,
            self.attachment_usage,
            self.ext.clone(),
        )?;

        let _drop_old = std::mem::replace(self, new_attachment_image);
        Ok(())
    }
}

impl Drop for VkAttachmentImage {
    fn drop(&mut self) {
        let image_view = self.image_view;

        self.drop_queue_ref
            .lock()
            .unwrap()
            .push(Box::new(move |dev, _| unsafe {
                dev.destroy_image_view(image_view, None);
            }))
    }
}