• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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