crystal-vk 0.2.0

Graphics wrapper for Vulkan
Documentation
use std::{
    collections::BTreeMap,
    error::Error,
    sync::{Arc, Mutex},
};

use ash::vk;

use crate::{device::Device, render::swapchain::Swapchain};

pub type QueuePool = BTreeMap<QueueFamilyInfo, Vec<Arc<Mutex<Queue>>>>;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct QueueFamilyInfo {
    pub flags: vk::QueueFlags,
    pub index: u32,
    pub queue_count: u32,
    pub present_support: bool,
}

impl QueueFamilyInfo {}

pub struct Queue {
    handle: vk::Queue,
    pub device: Arc<Device>,
}

unsafe impl Send for Queue {}

impl Queue {
    pub fn present(
        &self,
        present_info: &vk::PresentInfoKHR,
        swapchain: Arc<Swapchain>,
    ) -> Result<bool, Box<dyn Error>> {
        Ok(unsafe { swapchain.swapchain.queue_present(self.handle, present_info) }?)
    }

    pub fn submit(
        &mut self,
        submit_info: &[vk::SubmitInfo],
        fence: vk::Fence,
    ) -> Result<(), Box<dyn Error>> {
        unsafe {
            self.device
                .handle
                .queue_submit(self.handle, submit_info, fence)?
        }

        Ok(())
    }

    pub fn wait_idle(&mut self) -> Result<(), Box<dyn Error>> {
        Ok(unsafe { self.device.handle.queue_wait_idle(self.handle) }?)
    }

    pub fn instantiate(device: Arc<Device>) -> QueuePool {
        let mut queues = BTreeMap::new();

        device
            .physical_device
            .info
            .queue_families_info
            .iter()
            .for_each(|info| {
                let family_queues = (0..info.queue_count)
                    .map(|idx| {
                        Arc::new(Mutex::new(Queue {
                            device: device.clone(),
                            handle: unsafe { device.handle.get_device_queue(info.index, idx) },
                        }))
                    })
                    .collect::<Vec<Arc<Mutex<Queue>>>>();
                if info.queue_count > 0 {
                    queues.insert(*info, family_queues).unwrap_or_default();
                }
            });

        queues
    }
}