use super::vertex_input::IncompatibleVertexDefinitionError;
use crate::{
descriptor_set::layout::DescriptorSetLayoutCreationError,
format::{Format, NumericType},
pipeline::layout::{PipelineLayoutCreationError, PipelineLayoutSupersetError},
shader::ShaderInterfaceMismatchError,
OomError, RequirementNotMet, RequiresOneOf, VulkanError,
};
use std::{
error::Error,
fmt::{Display, Error as FmtError, Formatter},
};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum GraphicsPipelineCreationError {
RequirementNotMet {
required_for: &'static str,
requires_one_of: RequiresOneOf,
},
ColorAttachmentFormatBlendNotSupported { attachment_index: u32 },
ColorAttachmentFormatUsageNotSupported { attachment_index: u32 },
DepthAttachmentFormatUsageNotSupported,
DepthStencilAttachmentFormatMismatch,
FragmentShaderRenderPassIncompatible,
IncompatiblePipelineLayout(PipelineLayoutSupersetError),
IncompatibleSpecializationConstants,
IncompatibleVertexDefinition(IncompatibleVertexDefinitionError),
InvalidPrimitiveTopology,
InvalidNumPatchControlPoints,
MaxDiscardRectanglesExceeded {
max: u32,
obtained: u32,
},
MaxMultiviewViewCountExceeded { view_count: u32, max: u32 },
MaxVertexAttribDivisorExceeded {
binding: u32,
max: u32,
obtained: u32,
},
MaxVertexInputAttributesExceeded {
max: u32,
obtained: usize,
},
MaxVertexInputAttributeOffsetExceeded {
max: u32,
obtained: u32,
},
MaxVertexInputBindingsExceeded {
max: u32,
obtained: u32,
},
MaxVertexInputBindingStrideExceeded {
binding: u32,
max: u32,
obtained: u32,
},
MaxViewportsExceeded {
max: u32,
obtained: u32,
},
MinVertexInputBindingStrideAlignmentExceeded {
binding: u32,
max: u32,
obtained: u32,
},
MaxViewportDimensionsExceeded,
MismatchBlendingAttachmentsCount,
MultisampleRasterizationSamplesMismatch,
NoDepthAttachment,
NoStencilAttachment,
OomError(OomError),
DescriptorSetLayoutCreationError(DescriptorSetLayoutCreationError),
PipelineLayoutCreationError(PipelineLayoutCreationError),
ShaderStagesMismatch(ShaderInterfaceMismatchError),
StencilAttachmentFormatUsageNotSupported,
StrictLinesNotSupported,
TopologyNotMatchingGeometryShader,
VertexInputAttributeIncompatibleFormat {
location: u32,
shader_type: NumericType,
attribute_type: NumericType,
},
VertexInputAttributeInvalidBinding { location: u32, binding: u32 },
VertexInputAttributeMissing { location: u32 },
VertexInputAttributeUnsupportedFormat { location: u32, format: Format },
ViewportBoundsExceeded,
WrongShaderType,
WrongStencilState,
}
impl Error for GraphicsPipelineCreationError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::OomError(err) => Some(err),
Self::PipelineLayoutCreationError(err) => Some(err),
Self::IncompatiblePipelineLayout(err) => Some(err),
Self::ShaderStagesMismatch(err) => Some(err),
Self::IncompatibleVertexDefinition(err) => Some(err),
_ => None,
}
}
}
impl Display for GraphicsPipelineCreationError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::RequirementNotMet {
required_for,
requires_one_of,
} => write!(
f,
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::ColorAttachmentFormatBlendNotSupported { attachment_index } => write!(
f,
"color attachment {} has a format that does not support blending",
attachment_index,
),
Self::ColorAttachmentFormatUsageNotSupported { attachment_index } => write!(
f,
"color attachment {} has a format that does not support that usage",
attachment_index,
),
Self::DepthAttachmentFormatUsageNotSupported => write!(
f,
"the depth attachment has a format that does not support that usage",
),
Self::DepthStencilAttachmentFormatMismatch => write!(
f,
"the depth and stencil attachments have different formats",
),
Self::FragmentShaderRenderPassIncompatible => write!(
f,
"the output of the fragment shader is not compatible with what the render pass \
subpass expects",
),
Self::IncompatiblePipelineLayout(_) => write!(
f,
"the pipeline layout is not compatible with what the shaders expect",
),
Self::IncompatibleSpecializationConstants => write!(
f,
"the provided specialization constants are not compatible with what the shader \
expects",
),
Self::IncompatibleVertexDefinition(_) => write!(
f,
"the vertex definition is not compatible with the input of the vertex shader",
),
Self::InvalidPrimitiveTopology => write!(
f,
"trying to use a patch list without a tessellation shader, or a non-patch-list \
with a tessellation shader",
),
Self::InvalidNumPatchControlPoints => write!(
f,
"patch_control_points was not greater than 0 and less than or equal to the \
max_tessellation_patch_size limit",
),
Self::MaxDiscardRectanglesExceeded { .. } => write!(
f,
"the maximum number of discard rectangles has been exceeded",
),
Self::MaxMultiviewViewCountExceeded { .. } => {
write!(f, "the `max_multiview_view_count` limit has been exceeded")
}
Self::MaxVertexAttribDivisorExceeded { .. } => write!(
f,
"the maximum value for the instance rate divisor has been exceeded",
),
Self::MaxVertexInputAttributesExceeded { .. } => write!(
f,
"the maximum number of vertex attributes has been exceeded",
),
Self::MaxVertexInputAttributeOffsetExceeded { .. } => write!(
f,
"the maximum offset for a vertex attribute has been exceeded",
),
Self::MaxVertexInputBindingsExceeded { .. } => {
write!(f, "the maximum number of vertex sources has been exceeded")
}
Self::MaxVertexInputBindingStrideExceeded { .. } => write!(
f,
"the maximum stride value for vertex input (ie. the distance between two vertex \
elements) has been exceeded",
),
Self::MaxViewportsExceeded { .. } => {
write!(f, "the maximum number of viewports has been exceeded")
}
Self::MaxViewportDimensionsExceeded => {
write!(f, "the maximum dimensions of viewports has been exceeded")
}
Self::MinVertexInputBindingStrideAlignmentExceeded { .. } => write!(
f,
"the `min_vertex_input_binding_stride_alignment` limit has been exceeded",
),
Self::MismatchBlendingAttachmentsCount => write!(
f,
"the number of attachments specified in the blending does not match the number of \
attachments in the subpass",
),
Self::MultisampleRasterizationSamplesMismatch => write!(
f,
"the provided `rasterization_samples` does not match the number of samples of the \
render subpass",
),
Self::NoDepthAttachment => write!(
f,
"the depth attachment of the render pass does not match the depth test",
),
Self::NoStencilAttachment => write!(
f,
"the stencil attachment of the render pass does not match the stencil test",
),
Self::OomError(_) => write!(f, "not enough memory available"),
Self::DescriptorSetLayoutCreationError(_) => {
write!(f, "error while creating a descriptor set layout object")
}
Self::PipelineLayoutCreationError(_) => {
write!(f, "error while creating the pipeline layout object")
}
Self::ShaderStagesMismatch(_) => write!(
f,
"the output interface of one shader and the input interface of the next shader do \
not match",
),
Self::StencilAttachmentFormatUsageNotSupported => write!(
f,
"the stencil attachment has a format that does not support that usage",
),
Self::StrictLinesNotSupported => {
write!(f, "the strict_lines device property was false")
}
Self::TopologyNotMatchingGeometryShader => write!(
f,
"the primitives topology does not match what the geometry shader expects",
),
Self::VertexInputAttributeIncompatibleFormat {
location,
shader_type,
attribute_type,
} => write!(
f,
"the type of the shader input variable at location {} ({:?}) is not compatible \
with the format of the corresponding vertex input attribute ({:?})",
location, shader_type, attribute_type,
),
Self::VertexInputAttributeInvalidBinding { location, binding } => write!(
f,
"the binding number {} specified by vertex input attribute location {} does not \
exist in the provided list of binding descriptions",
binding, location,
),
Self::VertexInputAttributeMissing { location } => write!(
f,
"the vertex shader expects an input variable at location {}, but no vertex input \
attribute exists for that location",
location,
),
Self::VertexInputAttributeUnsupportedFormat { location, format } => write!(
f,
"the format {:?} specified by vertex input attribute location {} is not supported \
for vertex buffers",
format, location,
),
Self::ViewportBoundsExceeded => write!(
f,
"the minimum or maximum bounds of viewports have been exceeded",
),
Self::WrongShaderType => write!(f, "the wrong type of shader has been passed"),
Self::WrongStencilState => write!(f, "the requested stencil test is invalid"),
}
}
}
impl From<OomError> for GraphicsPipelineCreationError {
fn from(err: OomError) -> GraphicsPipelineCreationError {
Self::OomError(err)
}
}
impl From<DescriptorSetLayoutCreationError> for GraphicsPipelineCreationError {
fn from(err: DescriptorSetLayoutCreationError) -> Self {
Self::DescriptorSetLayoutCreationError(err)
}
}
impl From<PipelineLayoutCreationError> for GraphicsPipelineCreationError {
fn from(err: PipelineLayoutCreationError) -> Self {
Self::PipelineLayoutCreationError(err)
}
}
impl From<PipelineLayoutSupersetError> for GraphicsPipelineCreationError {
fn from(err: PipelineLayoutSupersetError) -> Self {
Self::IncompatiblePipelineLayout(err)
}
}
impl From<IncompatibleVertexDefinitionError> for GraphicsPipelineCreationError {
fn from(err: IncompatibleVertexDefinitionError) -> Self {
Self::IncompatibleVertexDefinition(err)
}
}
impl From<VulkanError> for GraphicsPipelineCreationError {
fn from(err: VulkanError) -> Self {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
err @ VulkanError::OutOfDeviceMemory => Self::OomError(OomError::from(err)),
_ => panic!("unexpected error: {:?}", err),
}
}
}
impl From<RequirementNotMet> for GraphicsPipelineCreationError {
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
requires_one_of: err.requires_one_of,
}
}
}