• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2016 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::buffer::BufferAccess;
11 use crate::format::Format;
12 use crate::pipeline::shader::ShaderInterface;
13 use crate::pipeline::vertex::VertexInput;
14 use crate::pipeline::vertex::VertexMemberTy;
15 use crate::SafeDeref;
16 use std::error;
17 use std::fmt;
18 use std::sync::Arc;
19 
20 /// Trait for types that describe the definition of the vertex input used by a graphics pipeline.
21 pub unsafe trait VertexDefinition:
22     VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>>
23 {
24     /// Builds the vertex definition to use to link this definition to a vertex shader's input
25     /// interface.
26     // TODO: remove error return, move checks to GraphicsPipelineBuilder
definition( &self, interface: &ShaderInterface, ) -> Result<VertexInput, IncompatibleVertexDefinitionError>27     fn definition(
28         &self,
29         interface: &ShaderInterface,
30     ) -> Result<VertexInput, IncompatibleVertexDefinitionError>;
31 }
32 
33 unsafe impl<T> VertexDefinition for T
34 where
35     T: SafeDeref,
36     T::Target: VertexDefinition,
37 {
38     #[inline]
definition( &self, interface: &ShaderInterface, ) -> Result<VertexInput, IncompatibleVertexDefinitionError>39     fn definition(
40         &self,
41         interface: &ShaderInterface,
42     ) -> Result<VertexInput, IncompatibleVertexDefinitionError> {
43         (**self).definition(interface)
44     }
45 }
46 
47 /// Error that can happen when the vertex definition doesn't match the input of the vertex shader.
48 #[derive(Clone, Debug, PartialEq, Eq)]
49 pub enum IncompatibleVertexDefinitionError {
50     /// An attribute of the vertex shader is missing in the vertex source.
51     MissingAttribute {
52         /// Name of the missing attribute.
53         attribute: String,
54     },
55 
56     /// The format of an attribute does not match.
57     FormatMismatch {
58         /// Name of the attribute.
59         attribute: String,
60         /// The format in the vertex shader.
61         shader: (Format, usize),
62         /// The format in the vertex definition.
63         definition: (VertexMemberTy, usize),
64     },
65 }
66 
67 impl error::Error for IncompatibleVertexDefinitionError {}
68 
69 impl fmt::Display for IncompatibleVertexDefinitionError {
70     #[inline]
fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>71     fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
72         write!(
73             fmt,
74             "{}",
75             match *self {
76                 IncompatibleVertexDefinitionError::MissingAttribute { .. } =>
77                     "an attribute is missing",
78                 IncompatibleVertexDefinitionError::FormatMismatch { .. } => {
79                     "the format of an attribute does not match"
80                 }
81             }
82         )
83     }
84 }
85 
86 /// Extension trait of `VertexDefinition`. The `L` parameter is an acceptable vertex source for this
87 /// vertex definition.
88 pub unsafe trait VertexSource<L> {
89     /// Checks and returns the list of buffers with offsets, number of vertices and number of instances.
90     // TODO: return error if problem
91     // TODO: better than a Vec
92     // TODO: return a struct instead
decode(&self, list: L) -> (Vec<Box<dyn BufferAccess + Send + Sync>>, usize, usize)93     fn decode(&self, list: L) -> (Vec<Box<dyn BufferAccess + Send + Sync>>, usize, usize);
94 }
95 
96 unsafe impl<L, T> VertexSource<L> for T
97 where
98     T: SafeDeref,
99     T::Target: VertexSource<L>,
100 {
101     #[inline]
decode(&self, list: L) -> (Vec<Box<dyn BufferAccess + Send + Sync>>, usize, usize)102     fn decode(&self, list: L) -> (Vec<Box<dyn BufferAccess + Send + Sync>>, usize, usize) {
103         (**self).decode(list)
104     }
105 }
106