// Copyright (c) 2017 The vulkano developers // Licensed under the Apache License, Version 2.0 // or the MIT // license , // at your option. All files in the project carrying such // notice may not be copied, modified, or distributed except // according to those terms. use super::vertex_input::IncompatibleVertexDefinitionError; use crate::{ descriptor_set::layout::DescriptorSetLayoutCreationError, format::{Format, NumericType}, pipeline::layout::{PipelineLayoutCreationError, PipelineLayoutSupersetError}, shader::{ShaderInterfaceMismatchError, ShaderScalarType}, OomError, RequirementNotMet, RequiresOneOf, VulkanError, }; use std::{ error::Error, fmt::{Display, Error as FmtError, Formatter}, }; /// Error that can happen when creating a graphics pipeline. #[derive(Clone, Debug, PartialEq, Eq)] pub enum GraphicsPipelineCreationError { RequirementNotMet { required_for: &'static str, requires_one_of: RequiresOneOf, }, /// A color attachment has a format that does not support blending. ColorAttachmentFormatBlendNotSupported { attachment_index: u32 }, /// A color attachment has a format that does not support that usage. ColorAttachmentFormatUsageNotSupported { attachment_index: u32 }, /// The depth attachment has a format that does not support that usage. DepthAttachmentFormatUsageNotSupported, /// The depth and stencil attachments have different formats. DepthStencilAttachmentFormatMismatch, /// The output of the fragment shader is not compatible with what the render pass subpass /// expects. FragmentShaderRenderPassIncompatible, /// The pipeline layout is not compatible with what the shaders expect. IncompatiblePipelineLayout(PipelineLayoutSupersetError), /// The provided specialization constants are not compatible with what the shader expects. IncompatibleSpecializationConstants, /// The vertex definition is not compatible with the input of the vertex shader. IncompatibleVertexDefinition(IncompatibleVertexDefinitionError), /// Tried to use a patch list without a tessellation shader, or a non-patch-list with a /// tessellation shader. InvalidPrimitiveTopology, /// `patch_control_points` was not greater than 0 and less than or equal to the `max_tessellation_patch_size` limit. InvalidNumPatchControlPoints, /// The maximum number of discard rectangles has been exceeded. MaxDiscardRectanglesExceeded { /// Maximum allowed value. max: u32, /// Value that was passed. obtained: u32, }, /// The `max_multiview_view_count` limit has been exceeded. MaxMultiviewViewCountExceeded { view_count: u32, max: u32 }, /// The maximum value for the instance rate divisor has been exceeded. MaxVertexAttribDivisorExceeded { /// Index of the faulty binding. binding: u32, /// Maximum allowed value. max: u32, /// Value that was passed. obtained: u32, }, /// The maximum number of vertex attributes has been exceeded. MaxVertexInputAttributesExceeded { /// Maximum allowed value. max: u32, /// Value that was passed. obtained: usize, }, /// The maximum offset for a vertex attribute has been exceeded. This means that your vertex /// struct is too large. MaxVertexInputAttributeOffsetExceeded { /// Maximum allowed value. max: u32, /// Value that was passed. obtained: u32, }, /// The maximum number of vertex sources has been exceeded. MaxVertexInputBindingsExceeded { /// Maximum allowed value. max: u32, /// Value that was passed. obtained: u32, }, /// The maximum stride value for vertex input (ie. the distance between two vertex elements) /// has been exceeded. MaxVertexInputBindingStrideExceeded { /// Index of the faulty binding. binding: u32, /// Maximum allowed value. max: u32, /// Value that was passed. obtained: u32, }, /// The maximum number of viewports has been exceeded. MaxViewportsExceeded { /// Maximum allowed value. max: u32, /// Value that was passed. obtained: u32, }, /// The `min_vertex_input_binding_stride_alignment` limit was exceeded. MinVertexInputBindingStrideAlignmentExceeded { /// Index of the faulty binding. binding: u32, /// Maximum allowed value. max: u32, /// Value that was passed. obtained: u32, }, /// The maximum dimensions of viewports has been exceeded. MaxViewportDimensionsExceeded, /// The number of attachments specified in the blending does not match the number of /// attachments in the subpass. MismatchBlendingAttachmentsCount, /// The provided `rasterization_samples` does not match the number of samples of the render /// subpass. MultisampleRasterizationSamplesMismatch, /// The depth test requires a depth attachment but render pass has no depth attachment, or /// depth writing is enabled and the depth attachment is read-only. NoDepthAttachment, /// The stencil test requires a stencil attachment but render pass has no stencil attachment, or /// stencil writing is enabled and the stencil attachment is read-only. NoStencilAttachment, /// Not enough memory. OomError(OomError), /// Error while creating a descriptor set layout object. DescriptorSetLayoutCreationError(DescriptorSetLayoutCreationError), /// Error while creating the pipeline layout object. PipelineLayoutCreationError(PipelineLayoutCreationError), /// The output interface of one shader and the input interface of the next shader do not match. ShaderStagesMismatch(ShaderInterfaceMismatchError), /// The stencil attachment has a format that does not support that usage. StencilAttachmentFormatUsageNotSupported, /// The [`strict_lines`](crate::device::Properties::strict_lines) device property was `false`. StrictLinesNotSupported, /// The primitives topology does not match what the geometry shader expects. TopologyNotMatchingGeometryShader, /// The type of the shader input variable at the given location is not compatible with the /// format of the corresponding vertex input attribute. VertexInputAttributeIncompatibleFormat { location: u32, shader_type: ShaderScalarType, attribute_type: NumericType, }, /// The location provided is assigned, but expected to unassigned due to the format of the /// prior location. VertexInputAttributeInvalidAssignedLocation { location: u32 }, /// The binding number specified by a vertex input attribute does not exist in the provided list /// of binding descriptions. VertexInputAttributeInvalidBinding { location: u32, binding: u32 }, /// The vertex shader expects an input variable at the given location, but no vertex input /// attribute exists for that location. VertexInputAttributeMissing { location: u32 }, /// The format specified by a vertex input attribute is not supported for vertex buffers. VertexInputAttributeUnsupportedFormat { location: u32, format: Format }, /// The minimum or maximum bounds of viewports have been exceeded. ViewportBoundsExceeded, /// The wrong type of shader has been passed. /// /// For example you passed a vertex shader as the fragment shader. WrongShaderType, /// The requested stencil test is invalid. 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::VertexInputAttributeInvalidAssignedLocation { location } => write!( f, "input attribute location {} is expected to be unassigned due to the format of the prior location", location, ), 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 for GraphicsPipelineCreationError { fn from(err: OomError) -> GraphicsPipelineCreationError { Self::OomError(err) } } impl From for GraphicsPipelineCreationError { fn from(err: DescriptorSetLayoutCreationError) -> Self { Self::DescriptorSetLayoutCreationError(err) } } impl From for GraphicsPipelineCreationError { fn from(err: PipelineLayoutCreationError) -> Self { Self::PipelineLayoutCreationError(err) } } impl From for GraphicsPipelineCreationError { fn from(err: PipelineLayoutSupersetError) -> Self { Self::IncompatiblePipelineLayout(err) } } impl From for GraphicsPipelineCreationError { fn from(err: IncompatibleVertexDefinitionError) -> Self { Self::IncompatibleVertexDefinition(err) } } impl From 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 for GraphicsPipelineCreationError { fn from(err: RequirementNotMet) -> Self { Self::RequirementNotMet { required_for: err.required_for, requires_one_of: err.requires_one_of, } } }