sierra 0.1.0

Vulkan-lite graphics API
Documentation
use {
    super::unexpected_result,
    crate::{
        out_of_host_memory,
        surface::{SurfaceError, SurfaceInfo},
        OutOfMemory,
    },
    erupt::{extensions::khr_surface::SurfaceKHR, vk1_0},
    std::{
        fmt::Debug,
        sync::atomic::{AtomicBool, Ordering},
    },
};

#[derive(Debug)]
pub(crate) struct Inner {
    pub handle: SurfaceKHR,
    pub used: AtomicBool,
    pub info: SurfaceInfo,
}

#[derive(Clone, Debug)]
#[repr(transparent)]
pub struct Surface {
    inner: std::sync::Arc<Inner>,
}

impl std::cmp::PartialEq for Surface {
    fn eq(&self, other: &Self) -> bool {
        std::ptr::eq(&*self.inner, &*other.inner)
    }
}

impl std::cmp::Eq for Surface {}

impl std::hash::Hash for Surface {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        std::ptr::hash(&*self.inner, state)
    }
}

impl Surface {
    pub(crate) fn make(handle: SurfaceKHR, used: AtomicBool, info: SurfaceInfo) -> Self {
        Surface {
            inner: std::sync::Arc::new(Inner { handle, used, info }),
        }
    }

    pub(crate) fn handle(&self) -> SurfaceKHR {
        self.inner.handle
    }

    pub(crate) fn mark_used(&self) -> Result<(), SurfaceError> {
        if self.inner.used.fetch_or(true, Ordering::SeqCst) {
            return Err(SurfaceError::AlreadyUsed);
        } else {
            Ok(())
        }
    }

    pub fn info(&self) -> &SurfaceInfo {
        &self.inner.info
    }
}

pub(crate) fn surface_error_from_erupt(err: vk1_0::Result) -> SurfaceError {
    match err {
        vk1_0::Result::ERROR_OUT_OF_HOST_MEMORY => out_of_host_memory(),
        vk1_0::Result::ERROR_OUT_OF_DEVICE_MEMORY => SurfaceError::OutOfMemory {
            source: OutOfMemory,
        },
        vk1_0::Result::ERROR_SURFACE_LOST_KHR => SurfaceError::SurfaceLost,
        _ => unexpected_result(err),
    }
}