aluminium 0.1.0

vulkan-based graphics engine
use ash::vk;
use crate::{VulkanError, core::Surface};

pub struct QueuePool {
    queues: Vec<Vec<Queue>>,
}

#[derive(Debug)]
pub struct Queue {
    pub raw: vk::Queue,
    pub flags: vk::QueueFlags,
    pub is_present: bool,
    pub family_index: u32,
    pub queue_index: u32
}

impl QueuePool {

    pub fn new(device: &ash::Device, phys_dev: &vk::PhysicalDevice, surface: &Surface, props: &[vk::QueueFamilyProperties]) -> Self {
        let mut queues = vec![];

        for (family_index, prop) in props.iter().enumerate() {
            let mut queue_family = vec![];
            for queue_index in 0..prop.queue_count {
                let queue = unsafe { device.get_device_queue(family_index as u32, queue_index) };
                let is_present = unsafe { surface.loader.get_physical_device_surface_support(*phys_dev, family_index as u32, surface.raw).map_err(VulkanError::Unknown).unwrap() };
                queue_family.push(Queue {
                    raw: queue,
                    flags: prop.queue_flags,
                    is_present,
                    family_index: family_index as u32,
                    queue_index
                });
            }
            queues.push(queue_family);
        }

        log::info!("Queues: {:#?}", queues);

        QueuePool {
            queues,
        }
    }

    pub fn get(&self, flags: vk::QueueFlags) -> Option<&Queue> {
        self.queues.iter()
            .flatten()
            .find(|q| q.flags.contains(flags))
    }

    pub fn get_present(&self) -> Option<&Queue> {
        self.queues.iter()
            .flatten()
            .find(|q| q.is_present)
    }

    pub fn get_dedicated(&self, flags: vk::QueueFlags) -> Option<&Queue> {
        self.queues.iter()
            .flatten()
            .find(|q| q.flags == flags)
            .or_else(|| self.get(flags))
    }

    pub fn graphics(&self) -> Option<&Queue> {
        self.get(vk::QueueFlags::GRAPHICS)
    }

    pub fn compute(&self) -> Option<&Queue> {
        self.get_dedicated(vk::QueueFlags::COMPUTE)
    }

    pub fn transfer(&self) -> Option<&Queue> {
        self.get_dedicated(vk::QueueFlags::TRANSFER)
    }
}