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