crystal-vk 0.0.4

Graphics wrapper for Vulkan
Documentation
pub mod physical_device;
pub mod queue;

use ash::vk;
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use std::{error::Error, sync::Arc};

use crate::{
    device::{
        physical_device::PhysicalDevice,
        queue::{Queue, QueuePool},
    },
    instance,
    render::surface::{
        self,
        window::{self, WindowSystemRawHandlers},
    },
};

pub struct Device {
    pub(crate) handle: ash::Device,
    pub(crate) instance: Arc<instance::Instance>,
    pub(crate) physical_device: Arc<physical_device::PhysicalDevice>,
    pub(crate) extensions: Vec<String>,
    pub(crate) surface: Option<Arc<surface::Surface>>,
}

unsafe impl Send for Device {}

impl Drop for Device {
    fn drop(&mut self) {
        unsafe {
            self.handle.device_wait_idle().unwrap();
            self.handle.destroy_device(None)
        }
    }
}

impl Device {
    pub fn compute<P>(
        physical_device_pick_predicate: P,
    ) -> Result<(Arc<Self>, QueuePool), Box<dyn Error>>
    where
        P: Fn(Vec<Arc<PhysicalDevice>>) -> Arc<PhysicalDevice>,
    {
        let device = Self::new_in(physical_device_pick_predicate, None)?;
        let queues = Queue::instantiate(device.clone());
        Ok((device, queues))
    }

    pub fn with_present<T: HasWindowHandle + HasDisplayHandle, P>(
        physical_device_pick_predicate: P,
        window: &T,
    ) -> Result<(Arc<Self>, QueuePool), Box<dyn Error>>
    where
        P: Fn(Vec<Arc<PhysicalDevice>>) -> Arc<PhysicalDevice>,
    {
        let handlers = WindowSystemRawHandlers::new(window)?;
        let device = Self::new_in(physical_device_pick_predicate, Some(handlers))?;
        let queues = Queue::instantiate(device.clone());
        Ok((device, queues))
    }

    fn new_in<P>(
        physical_device_pick_predicate: P,
        handlers: Option<window::WindowSystemRawHandlers>,
    ) -> Result<Arc<Self>, Box<dyn Error>>
    where
        P: Fn(Vec<Arc<PhysicalDevice>>) -> Arc<PhysicalDevice>,
    {
        let instance = instance::Instance::new(handlers)?;

        let surface = match handlers {
            Some(_) => Some(surface::Surface::new(instance.clone())?),
            None => None,
        };

        let physical_devices_raw = unsafe { instance.enumerate_physical_devices() }?;
        let physical_devices = unsafe {
            PhysicalDevice::new(instance.clone(), surface.clone(), physical_devices_raw)
        }?;

        let physical_device = physical_device_pick_predicate(physical_devices);

        let (device_handler, extensions) = physical_device.create_device(
            vk::PhysicalDeviceFeatures::default().sampler_anisotropy(true),
            handlers.is_some(),
        )?;

        let device = Arc::new(Self {
            handle: device_handler,
            instance,
            surface,
            physical_device,
            extensions,
        });

        Ok(device)
    }
}