use std::error;
use std::ffi::CStr;
use std::fmt;
use std::ptr;
use std::vec::IntoIter;
use Error;
use OomError;
use check_errors;
use instance::loader;
use instance::loader::LoadingError;
use version::Version;
use vk;
pub fn layers_list() -> Result<LayersIterator, LayersListError> {
layers_list_from_loader(loader::auto_loader()?)
}
pub fn layers_list_from_loader<L>(ptrs: &loader::FunctionPointers<L>)
-> Result<LayersIterator, LayersListError>
where L: loader::Loader
{
unsafe {
let entry_points = ptrs.entry_points();
let mut num = 0;
check_errors({
entry_points.EnumerateInstanceLayerProperties(&mut num, ptr::null_mut())
})?;
let mut layers: Vec<vk::LayerProperties> = Vec::with_capacity(num as usize);
check_errors({
entry_points
.EnumerateInstanceLayerProperties(&mut num, layers.as_mut_ptr())
})?;
layers.set_len(num as usize);
Ok(LayersIterator { iter: layers.into_iter() })
}
}
pub struct LayerProperties {
props: vk::LayerProperties,
}
impl LayerProperties {
#[inline]
pub fn name(&self) -> &str {
unsafe {
CStr::from_ptr(self.props.layerName.as_ptr())
.to_str()
.unwrap()
}
}
#[inline]
pub fn description(&self) -> &str {
unsafe {
CStr::from_ptr(self.props.description.as_ptr())
.to_str()
.unwrap()
}
}
#[inline]
pub fn vulkan_version(&self) -> Version {
Version::from_vulkan_version(self.props.specVersion)
}
#[inline]
pub fn implementation_version(&self) -> u32 {
self.props.implementationVersion
}
}
#[derive(Clone, Debug)]
pub enum LayersListError {
LoadingError(LoadingError),
OomError(OomError),
}
impl error::Error for LayersListError {
#[inline]
fn description(&self) -> &str {
match *self {
LayersListError::LoadingError(_) => "failed to load the Vulkan shared library",
LayersListError::OomError(_) => "not enough memory available",
}
}
#[inline]
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
LayersListError::LoadingError(ref err) => Some(err),
LayersListError::OomError(ref err) => Some(err),
}
}
}
impl fmt::Display for LayersListError {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(fmt, "{}", error::Error::description(self))
}
}
impl From<OomError> for LayersListError {
#[inline]
fn from(err: OomError) -> LayersListError {
LayersListError::OomError(err)
}
}
impl From<LoadingError> for LayersListError {
#[inline]
fn from(err: LoadingError) -> LayersListError {
LayersListError::LoadingError(err)
}
}
impl From<Error> for LayersListError {
#[inline]
fn from(err: Error) -> LayersListError {
match err {
err @ Error::OutOfHostMemory => LayersListError::OomError(OomError::from(err)),
err @ Error::OutOfDeviceMemory => LayersListError::OomError(OomError::from(err)),
_ => panic!("unexpected error: {:?}", err),
}
}
}
pub struct LayersIterator {
iter: IntoIter<vk::LayerProperties>,
}
impl Iterator for LayersIterator {
type Item = LayerProperties;
#[inline]
fn next(&mut self) -> Option<LayerProperties> {
self.iter.next().map(|p| LayerProperties { props: p })
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl ExactSizeIterator for LayersIterator {
}
#[cfg(test)]
mod tests {
use instance;
#[test]
fn layers_list() {
let mut list = match instance::layers_list() {
Ok(l) => l,
Err(_) => return,
};
while let Some(_) = list.next() {}
}
}