blob: 434426e65231fb1fcd532491930800b069452d84 [file] [log] [blame]
// Copyright (c) 2017 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
use crate::pipeline::input_assembly::PrimitiveTopology;
use crate::pipeline::layout::PipelineLayoutSupersetError;
use crate::pipeline::shader::ShaderInterfaceMismatchError;
use crate::pipeline::vertex::IncompatibleVertexDefinitionError;
use crate::Error;
use crate::OomError;
use std::error;
use std::fmt;
use std::u32;
/// Error that can happen when creating a graphics pipeline.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum GraphicsPipelineCreationError {
/// Not enough memory.
OomError(OomError),
/// 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 output interface of one shader and the input interface of the next shader does not match.
ShaderStagesMismatch(ShaderInterfaceMismatchError),
/// The output of the fragment shader is not compatible with what the render pass subpass
/// expects.
FragmentShaderRenderPassIncompatible,
/// The vertex definition is not compatible with the input of the vertex shader.
IncompatibleVertexDefinition(IncompatibleVertexDefinitionError),
/// 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 vertex sources has been exceeded.
MaxVertexInputBindingsExceeded {
/// Maximum allowed value.
max: u32,
/// Value that was passed.
obtained: u32,
},
/// 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 attributes has been exceeded.
MaxVertexInputAttributesExceeded {
/// Maximum allowed value.
max: u32,
/// Value that was passed.
obtained: usize,
},
/// The `vertex_attribute_instance_rate_divisor` feature must be enabled in order to use
/// instance rate divisors.
VertexAttributeInstanceRateDivisorFeatureNotEnabled,
/// The `vertex_attribute_instance_rate_zero_divisor` feature must be enabled in order to use
/// an instance rate divisor of zero.
VertexAttributeInstanceRateZeroDivisorFeatureNotEnabled,
/// 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 user requested to use primitive restart, but the primitive topology doesn't support it.
PrimitiveDoesntSupportPrimitiveRestart {
/// The topology that doesn't support primitive restart.
primitive: PrimitiveTopology,
},
/// The `multi_viewport` feature must be enabled in order to use multiple viewports at once.
MultiViewportFeatureNotEnabled,
/// The maximum number of viewports has been exceeded.
MaxViewportsExceeded {
/// Maximum allowed value.
max: u32,
/// Value that was passed.
obtained: u32,
},
/// The maximum dimensions of viewports has been exceeded.
MaxViewportDimensionsExceeded,
/// The minimum or maximum bounds of viewports have been exceeded.
ViewportBoundsExceeded,
/// The `wide_lines` feature must be enabled in order to use a line width greater than 1.0.
WideLinesFeatureNotEnabled,
/// The `depth_clamp` feature must be enabled in order to use depth clamping.
DepthClampFeatureNotEnabled,
/// The `depth_bias_clamp` feature must be enabled in order to use a depth bias clamp different
/// from 0.0.
DepthBiasClampFeatureNotEnabled,
/// The `fill_mode_non_solid` feature must be enabled in order to use a polygon mode different
/// from `Fill`.
FillModeNonSolidFeatureNotEnabled,
/// The `depth_bounds` feature must be enabled in order to use depth bounds testing.
DepthBoundsFeatureNotEnabled,
/// The requested stencil test is invalid.
WrongStencilState,
/// The primitives topology does not match what the geometry shader expects.
TopologyNotMatchingGeometryShader,
/// The `geometry_shader` feature must be enabled in order to use geometry shaders.
GeometryShaderFeatureNotEnabled,
/// The `tessellation_shader` feature must be enabled in order to use tessellation shaders.
TessellationShaderFeatureNotEnabled,
/// The number of attachments specified in the blending does not match the number of
/// attachments in the subpass.
MismatchBlendingAttachmentsCount,
/// The `independent_blend` feature must be enabled in order to use different blending
/// operations per attachment.
IndependentBlendFeatureNotEnabled,
/// The `logic_op` feature must be enabled in order to use logic operations.
LogicOpFeatureNotEnabled,
/// 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,
/// Tried to use a patch list without a tessellation shader, or a non-patch-list with a
/// tessellation shader.
InvalidPrimitiveTopology,
/// The `maxTessellationPatchSize` limit was exceeded.
MaxTessellationPatchSizeExceeded,
/// The wrong type of shader has been passed.
///
/// For example you passed a vertex shader as the fragment shader.
WrongShaderType,
/// The `sample_rate_shading` feature must be enabled in order to use sample shading.
SampleRateShadingFeatureNotEnabled,
/// The `alpha_to_one` feature must be enabled in order to use alpha-to-one.
AlphaToOneFeatureNotEnabled,
/// The device doesn't support using the `multiview´ feature with geometry shaders.
MultiviewGeometryShaderNotSupported,
/// The device doesn't support using the `multiview´ feature with tessellation shaders.
MultiviewTessellationShaderNotSupported,
}
impl error::Error for GraphicsPipelineCreationError {
#[inline]
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
GraphicsPipelineCreationError::OomError(ref err) => Some(err),
GraphicsPipelineCreationError::IncompatiblePipelineLayout(ref err) => Some(err),
GraphicsPipelineCreationError::ShaderStagesMismatch(ref err) => Some(err),
GraphicsPipelineCreationError::IncompatibleVertexDefinition(ref err) => Some(err),
_ => None,
}
}
}
impl fmt::Display for GraphicsPipelineCreationError {
// TODO: finish
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(
fmt,
"{}",
match *self {
GraphicsPipelineCreationError::OomError(_) => "not enough memory available",
GraphicsPipelineCreationError::ShaderStagesMismatch(_) => {
"the output interface of one shader and the input interface of the next shader does not match"
}
GraphicsPipelineCreationError::IncompatiblePipelineLayout(_) => {
"the pipeline layout is not compatible with what the shaders expect"
}
GraphicsPipelineCreationError::IncompatibleSpecializationConstants => {
"the provided specialization constants are not compatible with what the shader expects"
}
GraphicsPipelineCreationError::FragmentShaderRenderPassIncompatible => {
"the output of the fragment shader is not compatible with what the render pass \
subpass expects"
}
GraphicsPipelineCreationError::IncompatibleVertexDefinition(_) => {
"the vertex definition is not compatible with the input of the vertex shader"
}
GraphicsPipelineCreationError::MaxVertexInputBindingStrideExceeded { .. } => {
"the maximum stride value for vertex input (ie. the distance between two vertex \
elements) has been exceeded"
}
GraphicsPipelineCreationError::MaxVertexInputBindingsExceeded { .. } => {
"the maximum number of vertex sources has been exceeded"
}
GraphicsPipelineCreationError::MaxVertexInputAttributeOffsetExceeded { .. } => {
"the maximum offset for a vertex attribute has been exceeded"
}
GraphicsPipelineCreationError::MaxVertexInputAttributesExceeded { .. } => {
"the maximum number of vertex attributes has been exceeded"
}
GraphicsPipelineCreationError::VertexAttributeInstanceRateDivisorFeatureNotEnabled => {
"the `vertex_attribute_instance_rate_divisor` feature must be enabled in order to use instance rate divisors"
}
GraphicsPipelineCreationError::VertexAttributeInstanceRateZeroDivisorFeatureNotEnabled => {
"the `vertex_attribute_instance_rate_zero_divisor` feature must be enabled in order to use an instance rate divisor of zero"
}
GraphicsPipelineCreationError::MaxVertexAttribDivisorExceeded { .. } => {
"the maximum value for the instance rate divisor has been exceeded"
}
GraphicsPipelineCreationError::PrimitiveDoesntSupportPrimitiveRestart {
..
} => {
"the user requested to use primitive restart, but the primitive topology \
doesn't support it"
}
GraphicsPipelineCreationError::MultiViewportFeatureNotEnabled => {
"the `multi_viewport` feature must be enabled in order to use multiple viewports \
at once"
}
GraphicsPipelineCreationError::MaxViewportsExceeded { .. } => {
"the maximum number of viewports has been exceeded"
}
GraphicsPipelineCreationError::MaxViewportDimensionsExceeded => {
"the maximum dimensions of viewports has been exceeded"
}
GraphicsPipelineCreationError::ViewportBoundsExceeded => {
"the minimum or maximum bounds of viewports have been exceeded"
}
GraphicsPipelineCreationError::WideLinesFeatureNotEnabled => {
"the `wide_lines` feature must be enabled in order to use a line width \
greater than 1.0"
}
GraphicsPipelineCreationError::DepthClampFeatureNotEnabled => {
"the `depth_clamp` feature must be enabled in order to use depth clamping"
}
GraphicsPipelineCreationError::DepthBiasClampFeatureNotEnabled => {
"the `depth_bias_clamp` feature must be enabled in order to use a depth bias \
clamp different from 0.0."
}
GraphicsPipelineCreationError::FillModeNonSolidFeatureNotEnabled => {
"the `fill_mode_non_solid` feature must be enabled in order to use a polygon mode \
different from `Fill`"
}
GraphicsPipelineCreationError::DepthBoundsFeatureNotEnabled => {
"the `depth_bounds` feature must be enabled in order to use depth bounds testing"
}
GraphicsPipelineCreationError::WrongStencilState => {
"the requested stencil test is invalid"
}
GraphicsPipelineCreationError::TopologyNotMatchingGeometryShader => {
"the primitives topology does not match what the geometry shader expects"
}
GraphicsPipelineCreationError::GeometryShaderFeatureNotEnabled => {
"the `geometry_shader` feature must be enabled in order to use geometry shaders"
}
GraphicsPipelineCreationError::TessellationShaderFeatureNotEnabled => {
"the `tessellation_shader` feature must be enabled in order to use tessellation \
shaders"
}
GraphicsPipelineCreationError::MismatchBlendingAttachmentsCount => {
"the number of attachments specified in the blending does not match the number of \
attachments in the subpass"
}
GraphicsPipelineCreationError::IndependentBlendFeatureNotEnabled => {
"the `independent_blend` feature must be enabled in order to use different \
blending operations per attachment"
}
GraphicsPipelineCreationError::LogicOpFeatureNotEnabled => {
"the `logic_op` feature must be enabled in order to use logic operations"
}
GraphicsPipelineCreationError::NoDepthAttachment => {
"the depth attachment of the render pass does not match the depth test"
}
GraphicsPipelineCreationError::NoStencilAttachment => {
"the stencil attachment of the render pass does not match the stencil test"
}
GraphicsPipelineCreationError::InvalidPrimitiveTopology => {
"trying to use a patch list without a tessellation shader, or a non-patch-list \
with a tessellation shader"
}
GraphicsPipelineCreationError::MaxTessellationPatchSizeExceeded => {
"the maximum tessellation patch size was exceeded"
}
GraphicsPipelineCreationError::WrongShaderType => {
"the wrong type of shader has been passed"
}
GraphicsPipelineCreationError::SampleRateShadingFeatureNotEnabled => {
"the `sample_rate_shading` feature must be enabled in order to use sample shading"
}
GraphicsPipelineCreationError::AlphaToOneFeatureNotEnabled => {
"the `alpha_to_one` feature must be enabled in order to use alpha-to-one"
}
GraphicsPipelineCreationError::MultiviewGeometryShaderNotSupported => {
"the device doesn't support using the `multiview´ feature with geometry shaders"
}
GraphicsPipelineCreationError::MultiviewTessellationShaderNotSupported => {
"the device doesn't support using the `multiview´ feature with tessellation shaders"
}
}
)
}
}
impl From<OomError> for GraphicsPipelineCreationError {
#[inline]
fn from(err: OomError) -> GraphicsPipelineCreationError {
GraphicsPipelineCreationError::OomError(err)
}
}
impl From<PipelineLayoutSupersetError> for GraphicsPipelineCreationError {
#[inline]
fn from(err: PipelineLayoutSupersetError) -> GraphicsPipelineCreationError {
GraphicsPipelineCreationError::IncompatiblePipelineLayout(err)
}
}
impl From<IncompatibleVertexDefinitionError> for GraphicsPipelineCreationError {
#[inline]
fn from(err: IncompatibleVertexDefinitionError) -> GraphicsPipelineCreationError {
GraphicsPipelineCreationError::IncompatibleVertexDefinition(err)
}
}
impl From<Error> for GraphicsPipelineCreationError {
#[inline]
fn from(err: Error) -> GraphicsPipelineCreationError {
match err {
err @ Error::OutOfHostMemory => {
GraphicsPipelineCreationError::OomError(OomError::from(err))
}
err @ Error::OutOfDeviceMemory => {
GraphicsPipelineCreationError::OomError(OomError::from(err))
}
_ => panic!("unexpected error: {:?}", err),
}
}
}