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 super::vertex_input::IncompatibleVertexDefinitionError; 11 use crate::{ 12 descriptor_set::layout::DescriptorSetLayoutCreationError, 13 format::{Format, NumericType}, 14 pipeline::layout::{PipelineLayoutCreationError, PipelineLayoutSupersetError}, 15 shader::{ShaderInterfaceMismatchError, ShaderScalarType}, 16 OomError, RequirementNotMet, RequiresOneOf, VulkanError, 17 }; 18 use std::{ 19 error::Error, 20 fmt::{Display, Error as FmtError, Formatter}, 21 }; 22 23 /// Error that can happen when creating a graphics pipeline. 24 #[derive(Clone, Debug, PartialEq, Eq)] 25 pub enum GraphicsPipelineCreationError { 26 RequirementNotMet { 27 required_for: &'static str, 28 requires_one_of: RequiresOneOf, 29 }, 30 31 /// A color attachment has a format that does not support blending. 32 ColorAttachmentFormatBlendNotSupported { attachment_index: u32 }, 33 34 /// A color attachment has a format that does not support that usage. 35 ColorAttachmentFormatUsageNotSupported { attachment_index: u32 }, 36 37 /// The depth attachment has a format that does not support that usage. 38 DepthAttachmentFormatUsageNotSupported, 39 40 /// The depth and stencil attachments have different formats. 41 DepthStencilAttachmentFormatMismatch, 42 43 /// The output of the fragment shader is not compatible with what the render pass subpass 44 /// expects. 45 FragmentShaderRenderPassIncompatible, 46 47 /// The pipeline layout is not compatible with what the shaders expect. 48 IncompatiblePipelineLayout(PipelineLayoutSupersetError), 49 50 /// The provided specialization constants are not compatible with what the shader expects. 51 IncompatibleSpecializationConstants, 52 53 /// The vertex definition is not compatible with the input of the vertex shader. 54 IncompatibleVertexDefinition(IncompatibleVertexDefinitionError), 55 56 /// Tried to use a patch list without a tessellation shader, or a non-patch-list with a 57 /// tessellation shader. 58 InvalidPrimitiveTopology, 59 60 /// `patch_control_points` was not greater than 0 and less than or equal to the `max_tessellation_patch_size` limit. 61 InvalidNumPatchControlPoints, 62 63 /// The maximum number of discard rectangles has been exceeded. 64 MaxDiscardRectanglesExceeded { 65 /// Maximum allowed value. 66 max: u32, 67 /// Value that was passed. 68 obtained: u32, 69 }, 70 71 /// The `max_multiview_view_count` limit has been exceeded. 72 MaxMultiviewViewCountExceeded { view_count: u32, max: u32 }, 73 74 /// The maximum value for the instance rate divisor has been exceeded. 75 MaxVertexAttribDivisorExceeded { 76 /// Index of the faulty binding. 77 binding: u32, 78 /// Maximum allowed value. 79 max: u32, 80 /// Value that was passed. 81 obtained: u32, 82 }, 83 84 /// The maximum number of vertex attributes has been exceeded. 85 MaxVertexInputAttributesExceeded { 86 /// Maximum allowed value. 87 max: u32, 88 /// Value that was passed. 89 obtained: usize, 90 }, 91 92 /// The maximum offset for a vertex attribute has been exceeded. This means that your vertex 93 /// struct is too large. 94 MaxVertexInputAttributeOffsetExceeded { 95 /// Maximum allowed value. 96 max: u32, 97 /// Value that was passed. 98 obtained: u32, 99 }, 100 101 /// The maximum number of vertex sources has been exceeded. 102 MaxVertexInputBindingsExceeded { 103 /// Maximum allowed value. 104 max: u32, 105 /// Value that was passed. 106 obtained: u32, 107 }, 108 109 /// The maximum stride value for vertex input (ie. the distance between two vertex elements) 110 /// has been exceeded. 111 MaxVertexInputBindingStrideExceeded { 112 /// Index of the faulty binding. 113 binding: u32, 114 /// Maximum allowed value. 115 max: u32, 116 /// Value that was passed. 117 obtained: u32, 118 }, 119 120 /// The maximum number of viewports has been exceeded. 121 MaxViewportsExceeded { 122 /// Maximum allowed value. 123 max: u32, 124 /// Value that was passed. 125 obtained: u32, 126 }, 127 128 /// The `min_vertex_input_binding_stride_alignment` limit was exceeded. 129 MinVertexInputBindingStrideAlignmentExceeded { 130 /// Index of the faulty binding. 131 binding: u32, 132 /// Maximum allowed value. 133 max: u32, 134 /// Value that was passed. 135 obtained: u32, 136 }, 137 138 /// The maximum dimensions of viewports has been exceeded. 139 MaxViewportDimensionsExceeded, 140 141 /// The number of attachments specified in the blending does not match the number of 142 /// attachments in the subpass. 143 MismatchBlendingAttachmentsCount, 144 145 /// The provided `rasterization_samples` does not match the number of samples of the render 146 /// subpass. 147 MultisampleRasterizationSamplesMismatch, 148 149 /// The depth test requires a depth attachment but render pass has no depth attachment, or 150 /// depth writing is enabled and the depth attachment is read-only. 151 NoDepthAttachment, 152 153 /// The stencil test requires a stencil attachment but render pass has no stencil attachment, or 154 /// stencil writing is enabled and the stencil attachment is read-only. 155 NoStencilAttachment, 156 157 /// Not enough memory. 158 OomError(OomError), 159 160 /// Error while creating a descriptor set layout object. 161 DescriptorSetLayoutCreationError(DescriptorSetLayoutCreationError), 162 163 /// Error while creating the pipeline layout object. 164 PipelineLayoutCreationError(PipelineLayoutCreationError), 165 166 /// The output interface of one shader and the input interface of the next shader do not match. 167 ShaderStagesMismatch(ShaderInterfaceMismatchError), 168 169 /// The stencil attachment has a format that does not support that usage. 170 StencilAttachmentFormatUsageNotSupported, 171 172 /// The [`strict_lines`](crate::device::Properties::strict_lines) device property was `false`. 173 StrictLinesNotSupported, 174 175 /// The primitives topology does not match what the geometry shader expects. 176 TopologyNotMatchingGeometryShader, 177 178 /// The type of the shader input variable at the given location is not compatible with the 179 /// format of the corresponding vertex input attribute. 180 VertexInputAttributeIncompatibleFormat { 181 location: u32, 182 shader_type: ShaderScalarType, 183 attribute_type: NumericType, 184 }, 185 186 /// The location provided is assigned, but expected to unassigned due to the format of the 187 /// prior location. 188 VertexInputAttributeInvalidAssignedLocation { location: u32 }, 189 190 /// The binding number specified by a vertex input attribute does not exist in the provided list 191 /// of binding descriptions. 192 VertexInputAttributeInvalidBinding { location: u32, binding: u32 }, 193 194 /// The vertex shader expects an input variable at the given location, but no vertex input 195 /// attribute exists for that location. 196 VertexInputAttributeMissing { location: u32 }, 197 198 /// The format specified by a vertex input attribute is not supported for vertex buffers. 199 VertexInputAttributeUnsupportedFormat { location: u32, format: Format }, 200 201 /// The minimum or maximum bounds of viewports have been exceeded. 202 ViewportBoundsExceeded, 203 204 /// The wrong type of shader has been passed. 205 /// 206 /// For example you passed a vertex shader as the fragment shader. 207 WrongShaderType, 208 209 /// The requested stencil test is invalid. 210 WrongStencilState, 211 } 212 213 impl Error for GraphicsPipelineCreationError { source(&self) -> Option<&(dyn Error + 'static)>214 fn source(&self) -> Option<&(dyn Error + 'static)> { 215 match self { 216 Self::OomError(err) => Some(err), 217 Self::PipelineLayoutCreationError(err) => Some(err), 218 Self::IncompatiblePipelineLayout(err) => Some(err), 219 Self::ShaderStagesMismatch(err) => Some(err), 220 Self::IncompatibleVertexDefinition(err) => Some(err), 221 _ => None, 222 } 223 } 224 } 225 226 impl Display for GraphicsPipelineCreationError { fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError>227 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { 228 match self { 229 Self::RequirementNotMet { 230 required_for, 231 requires_one_of, 232 } => write!( 233 f, 234 "a requirement was not met for: {}; requires one of: {}", 235 required_for, requires_one_of, 236 ), 237 Self::ColorAttachmentFormatBlendNotSupported { attachment_index } => write!( 238 f, 239 "color attachment {} has a format that does not support blending", 240 attachment_index, 241 ), 242 Self::ColorAttachmentFormatUsageNotSupported { attachment_index } => write!( 243 f, 244 "color attachment {} has a format that does not support that usage", 245 attachment_index, 246 ), 247 Self::DepthAttachmentFormatUsageNotSupported => write!( 248 f, 249 "the depth attachment has a format that does not support that usage", 250 ), 251 Self::DepthStencilAttachmentFormatMismatch => write!( 252 f, 253 "the depth and stencil attachments have different formats", 254 ), 255 Self::FragmentShaderRenderPassIncompatible => write!( 256 f, 257 "the output of the fragment shader is not compatible with what the render pass \ 258 subpass expects", 259 ), 260 Self::IncompatiblePipelineLayout(_) => write!( 261 f, 262 "the pipeline layout is not compatible with what the shaders expect", 263 ), 264 Self::IncompatibleSpecializationConstants => write!( 265 f, 266 "the provided specialization constants are not compatible with what the shader \ 267 expects", 268 ), 269 Self::IncompatibleVertexDefinition(_) => write!( 270 f, 271 "the vertex definition is not compatible with the input of the vertex shader", 272 ), 273 Self::InvalidPrimitiveTopology => write!( 274 f, 275 "trying to use a patch list without a tessellation shader, or a non-patch-list \ 276 with a tessellation shader", 277 ), 278 Self::InvalidNumPatchControlPoints => write!( 279 f, 280 "patch_control_points was not greater than 0 and less than or equal to the \ 281 max_tessellation_patch_size limit", 282 ), 283 Self::MaxDiscardRectanglesExceeded { .. } => write!( 284 f, 285 "the maximum number of discard rectangles has been exceeded", 286 ), 287 Self::MaxMultiviewViewCountExceeded { .. } => { 288 write!(f, "the `max_multiview_view_count` limit has been exceeded") 289 } 290 Self::MaxVertexAttribDivisorExceeded { .. } => write!( 291 f, 292 "the maximum value for the instance rate divisor has been exceeded", 293 ), 294 Self::MaxVertexInputAttributesExceeded { .. } => write!( 295 f, 296 "the maximum number of vertex attributes has been exceeded", 297 ), 298 Self::MaxVertexInputAttributeOffsetExceeded { .. } => write!( 299 f, 300 "the maximum offset for a vertex attribute has been exceeded", 301 ), 302 Self::MaxVertexInputBindingsExceeded { .. } => { 303 write!(f, "the maximum number of vertex sources has been exceeded") 304 } 305 Self::MaxVertexInputBindingStrideExceeded { .. } => write!( 306 f, 307 "the maximum stride value for vertex input (ie. the distance between two vertex \ 308 elements) has been exceeded", 309 ), 310 Self::MaxViewportsExceeded { .. } => { 311 write!(f, "the maximum number of viewports has been exceeded") 312 } 313 Self::MaxViewportDimensionsExceeded => { 314 write!(f, "the maximum dimensions of viewports has been exceeded") 315 } 316 Self::MinVertexInputBindingStrideAlignmentExceeded { .. } => write!( 317 f, 318 "the `min_vertex_input_binding_stride_alignment` limit has been exceeded", 319 ), 320 Self::MismatchBlendingAttachmentsCount => write!( 321 f, 322 "the number of attachments specified in the blending does not match the number of \ 323 attachments in the subpass", 324 ), 325 Self::MultisampleRasterizationSamplesMismatch => write!( 326 f, 327 "the provided `rasterization_samples` does not match the number of samples of the \ 328 render subpass", 329 ), 330 Self::NoDepthAttachment => write!( 331 f, 332 "the depth attachment of the render pass does not match the depth test", 333 ), 334 Self::NoStencilAttachment => write!( 335 f, 336 "the stencil attachment of the render pass does not match the stencil test", 337 ), 338 Self::OomError(_) => write!(f, "not enough memory available"), 339 Self::DescriptorSetLayoutCreationError(_) => { 340 write!(f, "error while creating a descriptor set layout object") 341 } 342 Self::PipelineLayoutCreationError(_) => { 343 write!(f, "error while creating the pipeline layout object") 344 } 345 Self::ShaderStagesMismatch(_) => write!( 346 f, 347 "the output interface of one shader and the input interface of the next shader do \ 348 not match", 349 ), 350 Self::StencilAttachmentFormatUsageNotSupported => write!( 351 f, 352 "the stencil attachment has a format that does not support that usage", 353 ), 354 Self::StrictLinesNotSupported => { 355 write!(f, "the strict_lines device property was false") 356 } 357 Self::TopologyNotMatchingGeometryShader => write!( 358 f, 359 "the primitives topology does not match what the geometry shader expects", 360 ), 361 Self::VertexInputAttributeIncompatibleFormat { 362 location, 363 shader_type, 364 attribute_type, 365 } => write!( 366 f, 367 "the type of the shader input variable at location {} ({:?}) is not compatible \ 368 with the format of the corresponding vertex input attribute ({:?})", 369 location, shader_type, attribute_type, 370 ), 371 Self::VertexInputAttributeInvalidAssignedLocation { location } => write!( 372 f, 373 "input attribute location {} is expected to be unassigned due to the format of the prior location", 374 location, 375 ), 376 Self::VertexInputAttributeInvalidBinding { location, binding } => write!( 377 f, 378 "the binding number {} specified by vertex input attribute location {} does not \ 379 exist in the provided list of binding descriptions", 380 binding, location, 381 ), 382 Self::VertexInputAttributeMissing { location } => write!( 383 f, 384 "the vertex shader expects an input variable at location {}, but no vertex input \ 385 attribute exists for that location", 386 location, 387 ), 388 Self::VertexInputAttributeUnsupportedFormat { location, format } => write!( 389 f, 390 "the format {:?} specified by vertex input attribute location {} is not supported \ 391 for vertex buffers", 392 format, location, 393 ), 394 Self::ViewportBoundsExceeded => write!( 395 f, 396 "the minimum or maximum bounds of viewports have been exceeded", 397 ), 398 Self::WrongShaderType => write!(f, "the wrong type of shader has been passed"), 399 Self::WrongStencilState => write!(f, "the requested stencil test is invalid"), 400 } 401 } 402 } 403 404 impl From<OomError> for GraphicsPipelineCreationError { from(err: OomError) -> GraphicsPipelineCreationError405 fn from(err: OomError) -> GraphicsPipelineCreationError { 406 Self::OomError(err) 407 } 408 } 409 410 impl From<DescriptorSetLayoutCreationError> for GraphicsPipelineCreationError { from(err: DescriptorSetLayoutCreationError) -> Self411 fn from(err: DescriptorSetLayoutCreationError) -> Self { 412 Self::DescriptorSetLayoutCreationError(err) 413 } 414 } 415 416 impl From<PipelineLayoutCreationError> for GraphicsPipelineCreationError { from(err: PipelineLayoutCreationError) -> Self417 fn from(err: PipelineLayoutCreationError) -> Self { 418 Self::PipelineLayoutCreationError(err) 419 } 420 } 421 422 impl From<PipelineLayoutSupersetError> for GraphicsPipelineCreationError { from(err: PipelineLayoutSupersetError) -> Self423 fn from(err: PipelineLayoutSupersetError) -> Self { 424 Self::IncompatiblePipelineLayout(err) 425 } 426 } 427 428 impl From<IncompatibleVertexDefinitionError> for GraphicsPipelineCreationError { from(err: IncompatibleVertexDefinitionError) -> Self429 fn from(err: IncompatibleVertexDefinitionError) -> Self { 430 Self::IncompatibleVertexDefinition(err) 431 } 432 } 433 434 impl From<VulkanError> for GraphicsPipelineCreationError { from(err: VulkanError) -> Self435 fn from(err: VulkanError) -> Self { 436 match err { 437 err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)), 438 err @ VulkanError::OutOfDeviceMemory => Self::OomError(OomError::from(err)), 439 _ => panic!("unexpected error: {:?}", err), 440 } 441 } 442 } 443 444 impl From<RequirementNotMet> for GraphicsPipelineCreationError { from(err: RequirementNotMet) -> Self445 fn from(err: RequirementNotMet) -> Self { 446 Self::RequirementNotMet { 447 required_for: err.required_for, 448 requires_one_of: err.requires_one_of, 449 } 450 } 451 } 452