1 // Copyright (c) 2017 The vulkano developers 2 // Licensed under the Apache License, Version 2.0 3 // <LICENSE-APACHE or 4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT 5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, 6 // at your option. All files in the project carrying such 7 // notice may not be copied, modified, or distributed except 8 // according to those terms. 9 10 use crate::pipeline::input_assembly::PrimitiveTopology; 11 use crate::pipeline::layout::PipelineLayoutSupersetError; 12 use crate::pipeline::shader::ShaderInterfaceMismatchError; 13 use crate::pipeline::vertex::IncompatibleVertexDefinitionError; 14 use crate::Error; 15 use crate::OomError; 16 use std::error; 17 use std::fmt; 18 use std::u32; 19 20 /// Error that can happen when creating a graphics pipeline. 21 #[derive(Clone, Debug, PartialEq, Eq)] 22 pub enum GraphicsPipelineCreationError { 23 /// Not enough memory. 24 OomError(OomError), 25 26 /// The pipeline layout is not compatible with what the shaders expect. 27 IncompatiblePipelineLayout(PipelineLayoutSupersetError), 28 29 /// The provided specialization constants are not compatible with what the shader expects. 30 IncompatibleSpecializationConstants, 31 32 /// The output interface of one shader and the input interface of the next shader does not match. 33 ShaderStagesMismatch(ShaderInterfaceMismatchError), 34 35 /// The output of the fragment shader is not compatible with what the render pass subpass 36 /// expects. 37 FragmentShaderRenderPassIncompatible, 38 39 /// The vertex definition is not compatible with the input of the vertex shader. 40 IncompatibleVertexDefinition(IncompatibleVertexDefinitionError), 41 42 /// The maximum stride value for vertex input (ie. the distance between two vertex elements) 43 /// has been exceeded. 44 MaxVertexInputBindingStrideExceeded { 45 /// Index of the faulty binding. 46 binding: u32, 47 /// Maximum allowed value. 48 max: u32, 49 /// Value that was passed. 50 obtained: u32, 51 }, 52 53 /// The maximum number of vertex sources has been exceeded. 54 MaxVertexInputBindingsExceeded { 55 /// Maximum allowed value. 56 max: u32, 57 /// Value that was passed. 58 obtained: u32, 59 }, 60 61 /// The maximum offset for a vertex attribute has been exceeded. This means that your vertex 62 /// struct is too large. 63 MaxVertexInputAttributeOffsetExceeded { 64 /// Maximum allowed value. 65 max: u32, 66 /// Value that was passed. 67 obtained: u32, 68 }, 69 70 /// The maximum number of vertex attributes has been exceeded. 71 MaxVertexInputAttributesExceeded { 72 /// Maximum allowed value. 73 max: u32, 74 /// Value that was passed. 75 obtained: usize, 76 }, 77 78 /// The `vertex_attribute_instance_rate_divisor` feature must be enabled in order to use 79 /// instance rate divisors. 80 VertexAttributeInstanceRateDivisorFeatureNotEnabled, 81 82 /// The `vertex_attribute_instance_rate_zero_divisor` feature must be enabled in order to use 83 /// an instance rate divisor of zero. 84 VertexAttributeInstanceRateZeroDivisorFeatureNotEnabled, 85 86 /// The maximum value for the instance rate divisor has been exceeded. 87 MaxVertexAttribDivisorExceeded { 88 /// Index of the faulty binding. 89 binding: u32, 90 /// Maximum allowed value. 91 max: u32, 92 /// Value that was passed. 93 obtained: u32, 94 }, 95 96 /// The user requested to use primitive restart, but the primitive topology doesn't support it. 97 PrimitiveDoesntSupportPrimitiveRestart { 98 /// The topology that doesn't support primitive restart. 99 primitive: PrimitiveTopology, 100 }, 101 102 /// The `multi_viewport` feature must be enabled in order to use multiple viewports at once. 103 MultiViewportFeatureNotEnabled, 104 105 /// The maximum number of viewports has been exceeded. 106 MaxViewportsExceeded { 107 /// Maximum allowed value. 108 max: u32, 109 /// Value that was passed. 110 obtained: u32, 111 }, 112 113 /// The maximum dimensions of viewports has been exceeded. 114 MaxViewportDimensionsExceeded, 115 116 /// The minimum or maximum bounds of viewports have been exceeded. 117 ViewportBoundsExceeded, 118 119 /// The `wide_lines` feature must be enabled in order to use a line width greater than 1.0. 120 WideLinesFeatureNotEnabled, 121 122 /// The `depth_clamp` feature must be enabled in order to use depth clamping. 123 DepthClampFeatureNotEnabled, 124 125 /// The `depth_bias_clamp` feature must be enabled in order to use a depth bias clamp different 126 /// from 0.0. 127 DepthBiasClampFeatureNotEnabled, 128 129 /// The `fill_mode_non_solid` feature must be enabled in order to use a polygon mode different 130 /// from `Fill`. 131 FillModeNonSolidFeatureNotEnabled, 132 133 /// The `depth_bounds` feature must be enabled in order to use depth bounds testing. 134 DepthBoundsFeatureNotEnabled, 135 136 /// The requested stencil test is invalid. 137 WrongStencilState, 138 139 /// The primitives topology does not match what the geometry shader expects. 140 TopologyNotMatchingGeometryShader, 141 142 /// The `geometry_shader` feature must be enabled in order to use geometry shaders. 143 GeometryShaderFeatureNotEnabled, 144 145 /// The `tessellation_shader` feature must be enabled in order to use tessellation shaders. 146 TessellationShaderFeatureNotEnabled, 147 148 /// The number of attachments specified in the blending does not match the number of 149 /// attachments in the subpass. 150 MismatchBlendingAttachmentsCount, 151 152 /// The `independent_blend` feature must be enabled in order to use different blending 153 /// operations per attachment. 154 IndependentBlendFeatureNotEnabled, 155 156 /// The `logic_op` feature must be enabled in order to use logic operations. 157 LogicOpFeatureNotEnabled, 158 159 /// The depth test requires a depth attachment but render pass has no depth attachment, or 160 /// depth writing is enabled and the depth attachment is read-only. 161 NoDepthAttachment, 162 163 /// The stencil test requires a stencil attachment but render pass has no stencil attachment, or 164 /// stencil writing is enabled and the stencil attachment is read-only. 165 NoStencilAttachment, 166 167 /// Tried to use a patch list without a tessellation shader, or a non-patch-list with a 168 /// tessellation shader. 169 InvalidPrimitiveTopology, 170 171 /// The `maxTessellationPatchSize` limit was exceeded. 172 MaxTessellationPatchSizeExceeded, 173 174 /// The wrong type of shader has been passed. 175 /// 176 /// For example you passed a vertex shader as the fragment shader. 177 WrongShaderType, 178 179 /// The `sample_rate_shading` feature must be enabled in order to use sample shading. 180 SampleRateShadingFeatureNotEnabled, 181 182 /// The `alpha_to_one` feature must be enabled in order to use alpha-to-one. 183 AlphaToOneFeatureNotEnabled, 184 185 /// The device doesn't support using the `multiview´ feature with geometry shaders. 186 MultiviewGeometryShaderNotSupported, 187 188 /// The device doesn't support using the `multiview´ feature with tessellation shaders. 189 MultiviewTessellationShaderNotSupported, 190 } 191 192 impl error::Error for GraphicsPipelineCreationError { 193 #[inline] source(&self) -> Option<&(dyn error::Error + 'static)>194 fn source(&self) -> Option<&(dyn error::Error + 'static)> { 195 match *self { 196 GraphicsPipelineCreationError::OomError(ref err) => Some(err), 197 GraphicsPipelineCreationError::IncompatiblePipelineLayout(ref err) => Some(err), 198 GraphicsPipelineCreationError::ShaderStagesMismatch(ref err) => Some(err), 199 GraphicsPipelineCreationError::IncompatibleVertexDefinition(ref err) => Some(err), 200 _ => None, 201 } 202 } 203 } 204 205 impl fmt::Display for GraphicsPipelineCreationError { 206 // TODO: finish 207 #[inline] fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>208 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { 209 write!( 210 fmt, 211 "{}", 212 match *self { 213 GraphicsPipelineCreationError::OomError(_) => "not enough memory available", 214 GraphicsPipelineCreationError::ShaderStagesMismatch(_) => { 215 "the output interface of one shader and the input interface of the next shader does not match" 216 } 217 GraphicsPipelineCreationError::IncompatiblePipelineLayout(_) => { 218 "the pipeline layout is not compatible with what the shaders expect" 219 } 220 GraphicsPipelineCreationError::IncompatibleSpecializationConstants => { 221 "the provided specialization constants are not compatible with what the shader expects" 222 } 223 GraphicsPipelineCreationError::FragmentShaderRenderPassIncompatible => { 224 "the output of the fragment shader is not compatible with what the render pass \ 225 subpass expects" 226 } 227 GraphicsPipelineCreationError::IncompatibleVertexDefinition(_) => { 228 "the vertex definition is not compatible with the input of the vertex shader" 229 } 230 GraphicsPipelineCreationError::MaxVertexInputBindingStrideExceeded { .. } => { 231 "the maximum stride value for vertex input (ie. the distance between two vertex \ 232 elements) has been exceeded" 233 } 234 GraphicsPipelineCreationError::MaxVertexInputBindingsExceeded { .. } => { 235 "the maximum number of vertex sources has been exceeded" 236 } 237 GraphicsPipelineCreationError::MaxVertexInputAttributeOffsetExceeded { .. } => { 238 "the maximum offset for a vertex attribute has been exceeded" 239 } 240 GraphicsPipelineCreationError::MaxVertexInputAttributesExceeded { .. } => { 241 "the maximum number of vertex attributes has been exceeded" 242 } 243 GraphicsPipelineCreationError::VertexAttributeInstanceRateDivisorFeatureNotEnabled => { 244 "the `vertex_attribute_instance_rate_divisor` feature must be enabled in order to use instance rate divisors" 245 } 246 GraphicsPipelineCreationError::VertexAttributeInstanceRateZeroDivisorFeatureNotEnabled => { 247 "the `vertex_attribute_instance_rate_zero_divisor` feature must be enabled in order to use an instance rate divisor of zero" 248 } 249 GraphicsPipelineCreationError::MaxVertexAttribDivisorExceeded { .. } => { 250 "the maximum value for the instance rate divisor has been exceeded" 251 } 252 GraphicsPipelineCreationError::PrimitiveDoesntSupportPrimitiveRestart { 253 .. 254 } => { 255 "the user requested to use primitive restart, but the primitive topology \ 256 doesn't support it" 257 } 258 GraphicsPipelineCreationError::MultiViewportFeatureNotEnabled => { 259 "the `multi_viewport` feature must be enabled in order to use multiple viewports \ 260 at once" 261 } 262 GraphicsPipelineCreationError::MaxViewportsExceeded { .. } => { 263 "the maximum number of viewports has been exceeded" 264 } 265 GraphicsPipelineCreationError::MaxViewportDimensionsExceeded => { 266 "the maximum dimensions of viewports has been exceeded" 267 } 268 GraphicsPipelineCreationError::ViewportBoundsExceeded => { 269 "the minimum or maximum bounds of viewports have been exceeded" 270 } 271 GraphicsPipelineCreationError::WideLinesFeatureNotEnabled => { 272 "the `wide_lines` feature must be enabled in order to use a line width \ 273 greater than 1.0" 274 } 275 GraphicsPipelineCreationError::DepthClampFeatureNotEnabled => { 276 "the `depth_clamp` feature must be enabled in order to use depth clamping" 277 } 278 GraphicsPipelineCreationError::DepthBiasClampFeatureNotEnabled => { 279 "the `depth_bias_clamp` feature must be enabled in order to use a depth bias \ 280 clamp different from 0.0." 281 } 282 GraphicsPipelineCreationError::FillModeNonSolidFeatureNotEnabled => { 283 "the `fill_mode_non_solid` feature must be enabled in order to use a polygon mode \ 284 different from `Fill`" 285 } 286 GraphicsPipelineCreationError::DepthBoundsFeatureNotEnabled => { 287 "the `depth_bounds` feature must be enabled in order to use depth bounds testing" 288 } 289 GraphicsPipelineCreationError::WrongStencilState => { 290 "the requested stencil test is invalid" 291 } 292 GraphicsPipelineCreationError::TopologyNotMatchingGeometryShader => { 293 "the primitives topology does not match what the geometry shader expects" 294 } 295 GraphicsPipelineCreationError::GeometryShaderFeatureNotEnabled => { 296 "the `geometry_shader` feature must be enabled in order to use geometry shaders" 297 } 298 GraphicsPipelineCreationError::TessellationShaderFeatureNotEnabled => { 299 "the `tessellation_shader` feature must be enabled in order to use tessellation \ 300 shaders" 301 } 302 GraphicsPipelineCreationError::MismatchBlendingAttachmentsCount => { 303 "the number of attachments specified in the blending does not match the number of \ 304 attachments in the subpass" 305 } 306 GraphicsPipelineCreationError::IndependentBlendFeatureNotEnabled => { 307 "the `independent_blend` feature must be enabled in order to use different \ 308 blending operations per attachment" 309 } 310 GraphicsPipelineCreationError::LogicOpFeatureNotEnabled => { 311 "the `logic_op` feature must be enabled in order to use logic operations" 312 } 313 GraphicsPipelineCreationError::NoDepthAttachment => { 314 "the depth attachment of the render pass does not match the depth test" 315 } 316 GraphicsPipelineCreationError::NoStencilAttachment => { 317 "the stencil attachment of the render pass does not match the stencil test" 318 } 319 GraphicsPipelineCreationError::InvalidPrimitiveTopology => { 320 "trying to use a patch list without a tessellation shader, or a non-patch-list \ 321 with a tessellation shader" 322 } 323 GraphicsPipelineCreationError::MaxTessellationPatchSizeExceeded => { 324 "the maximum tessellation patch size was exceeded" 325 } 326 GraphicsPipelineCreationError::WrongShaderType => { 327 "the wrong type of shader has been passed" 328 } 329 GraphicsPipelineCreationError::SampleRateShadingFeatureNotEnabled => { 330 "the `sample_rate_shading` feature must be enabled in order to use sample shading" 331 } 332 GraphicsPipelineCreationError::AlphaToOneFeatureNotEnabled => { 333 "the `alpha_to_one` feature must be enabled in order to use alpha-to-one" 334 } 335 GraphicsPipelineCreationError::MultiviewGeometryShaderNotSupported => { 336 "the device doesn't support using the `multiview´ feature with geometry shaders" 337 } 338 GraphicsPipelineCreationError::MultiviewTessellationShaderNotSupported => { 339 "the device doesn't support using the `multiview´ feature with tessellation shaders" 340 } 341 } 342 ) 343 } 344 } 345 346 impl From<OomError> for GraphicsPipelineCreationError { 347 #[inline] from(err: OomError) -> GraphicsPipelineCreationError348 fn from(err: OomError) -> GraphicsPipelineCreationError { 349 GraphicsPipelineCreationError::OomError(err) 350 } 351 } 352 353 impl From<PipelineLayoutSupersetError> for GraphicsPipelineCreationError { 354 #[inline] from(err: PipelineLayoutSupersetError) -> GraphicsPipelineCreationError355 fn from(err: PipelineLayoutSupersetError) -> GraphicsPipelineCreationError { 356 GraphicsPipelineCreationError::IncompatiblePipelineLayout(err) 357 } 358 } 359 360 impl From<IncompatibleVertexDefinitionError> for GraphicsPipelineCreationError { 361 #[inline] from(err: IncompatibleVertexDefinitionError) -> GraphicsPipelineCreationError362 fn from(err: IncompatibleVertexDefinitionError) -> GraphicsPipelineCreationError { 363 GraphicsPipelineCreationError::IncompatibleVertexDefinition(err) 364 } 365 } 366 367 impl From<Error> for GraphicsPipelineCreationError { 368 #[inline] from(err: Error) -> GraphicsPipelineCreationError369 fn from(err: Error) -> GraphicsPipelineCreationError { 370 match err { 371 err @ Error::OutOfHostMemory => { 372 GraphicsPipelineCreationError::OomError(OomError::from(err)) 373 } 374 err @ Error::OutOfDeviceMemory => { 375 GraphicsPipelineCreationError::OomError(OomError::from(err)) 376 } 377 _ => panic!("unexpected error: {:?}", err), 378 } 379 } 380 } 381