use std::ffi::NulError;
use std::sync::PoisonError;
use ash;
use gpu_allocator::AllocationError;
use thiserror::Error;
use crate::core::device::ExtensionID;
#[derive(Error, Debug)]
pub enum Error {
#[error("Failed to load Vulkan.")]
LoadFailed(ash::LoadingError),
#[error("Invalid C string")]
InvalidString(NulError),
#[error("Vulkan error: `{0}`")]
VkError(ash::vk::Result),
#[error("Expected a window context.")]
NoWindow,
#[error("No physical device found matching requirements.")]
NoGPU,
#[error("No supported surface formats found.")]
NoSurfaceFormat,
#[error("No queue found that supports presentation. Only headless mode is supported.")]
NoPresentQueue,
#[error(
"No queue found for requested domain. Did you forget a queue request on initialization?"
)]
NoCapableQueue,
#[error("Vulkan allocation error: `{0}`")]
AllocationError(AllocationError),
#[error("Task graph contains cycle.")]
GraphHasCycle,
#[error("Implementation error. Node not found. Please open an issue.")]
NodeNotFound,
#[error("Illegal task graph using the same resource in different ways.")]
IllegalTaskGraph,
#[error("No resource bound to virtual resource `{0}`")]
NoResourceBound(String),
#[error("Named pipeline `{0}` not found.")]
PipelineNotFound(String),
#[error("Tried to add a vertex attribute to a vertex binding that does not exist.")]
NoVertexBinding,
#[error("Empty descriptor set.")]
EmptyDescriptorBinding,
#[error("No descriptor set layout was given. Always create descriptor sets through a command buffer after binding a pipeline.")]
NoDescriptorSetLayout,
#[error("No clear value specified for an attachment with `VK_LOAD_OP_CLEAR`")]
NoClearValue,
#[error("Poisoned mutex")]
PoisonError,
#[error("Buffer view is not a valid range in the parent buffer.")]
BufferViewOutOfRange,
#[error("Buffer copy has invalid buffer views as range.")]
InvalidBufferCopy,
#[error("Requested mappable buffer, but buffer does not have a memory map")]
UnmappableBuffer,
#[error("Shader does not have an entry point.")]
NoEntryPoint,
#[error("Shader uses aliased descriptor `{0}`, which is currently not supported.")]
AliasedDescriptor(String),
#[error("Missing shader reflection information in call that requires it.")]
NoReflectionInformation,
#[error("Descriptor `{0}` does not exist.")]
NoBinding(String),
#[error("Returned as a result from ExecutionManager::try_on_domain to indicate the queue is currently locked.")]
QueueLocked,
#[error("Tried to bind descriptors to command buffer with no descriptor cache")]
NoDescriptorCache,
#[error("Tried to bind pipeline to command buffer with no pipeline cache")]
NoPipelineCache,
#[error("Tried to obtain a graphics pipeline outside of a render pass.")]
NoRenderpass,
#[error("Extension {0} required for this feature, but not enabled.")]
ExtensionNotSupported(ExtensionID),
#[error("Uncategorized error: `{0}`")]
Uncategorized(&'static str),
}
impl From<ash::LoadingError> for Error {
fn from(value: ash::LoadingError) -> Self {
Error::LoadFailed(value)
}
}
impl From<NulError> for Error {
fn from(value: NulError) -> Self {
Error::InvalidString(value)
}
}
impl From<ash::vk::Result> for Error {
fn from(value: ash::vk::Result) -> Self {
Error::VkError(value)
}
}
impl From<AllocationError> for Error {
fn from(value: AllocationError) -> Self {
Error::AllocationError(value)
}
}
impl From<(Vec<ash::vk::Pipeline>, ash::vk::Result)> for Error {
fn from(_: (Vec<ash::vk::Pipeline>, ash::vk::Result)) -> Self {
Error::Uncategorized("Pipeline creation failed")
}
}
impl<T> From<PoisonError<T>> for Error {
fn from(_: PoisonError<T>) -> Self {
Error::PoisonError
}
}