• 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 std::error;
11 use std::fmt;
12 
13 use crate::buffer::BufferAccess;
14 use crate::device::DeviceOwned;
15 use crate::pipeline::vertex::VertexSource;
16 use crate::pipeline::GraphicsPipelineAbstract;
17 use crate::VulkanObject;
18 
19 /// Checks whether vertex buffers can be bound.
20 ///
21 /// # Panic
22 ///
23 /// - Panics if one of the vertex buffers was not created with the same device as `pipeline`.
24 ///
check_vertex_buffers<GP, V>( pipeline: &GP, vertex_buffers: V, ) -> Result<CheckVertexBuffer, CheckVertexBufferError> where GP: GraphicsPipelineAbstract + DeviceOwned + VertexSource<V>,25 pub fn check_vertex_buffers<GP, V>(
26     pipeline: &GP,
27     vertex_buffers: V,
28 ) -> Result<CheckVertexBuffer, CheckVertexBufferError>
29 where
30     GP: GraphicsPipelineAbstract + DeviceOwned + VertexSource<V>,
31 {
32     let (vertex_buffers, vertex_count, instance_count) = pipeline.decode(vertex_buffers);
33 
34     for (num, buf) in vertex_buffers.iter().enumerate() {
35         assert_eq!(
36             buf.inner().buffer.device().internal_object(),
37             pipeline.device().internal_object()
38         );
39 
40         if !buf.inner().buffer.usage().vertex_buffer {
41             return Err(CheckVertexBufferError::BufferMissingUsage { num_buffer: num });
42         }
43     }
44 
45     if let Some(multiview) = pipeline.subpass().render_pass().desc().multiview() {
46         let max_instance_index = pipeline
47             .device()
48             .physical_device()
49             .properties()
50             .max_multiview_instance_index
51             .unwrap_or(0) as usize;
52 
53         // vulkano currently always uses `0` as the first instance which means the highest
54         // used index will just be `instance_count - 1`
55         if instance_count > max_instance_index + 1 {
56             return Err(CheckVertexBufferError::TooManyInstances {
57                 instance_count,
58                 max_instance_count: max_instance_index + 1,
59             });
60         }
61     }
62 
63     Ok(CheckVertexBuffer {
64         vertex_buffers,
65         vertex_count: vertex_count as u32,
66         instance_count: instance_count as u32,
67     })
68 }
69 
70 /// Information returned if `check_vertex_buffer` succeeds.
71 pub struct CheckVertexBuffer {
72     /// The list of vertex buffers.
73     pub vertex_buffers: Vec<Box<dyn BufferAccess + Send + Sync>>,
74     /// Number of vertices available in the intersection of the buffers.
75     pub vertex_count: u32,
76     /// Number of instances available in the intersection of the buffers.
77     pub instance_count: u32,
78 }
79 
80 /// Error that can happen when checking whether the vertex buffers are valid.
81 #[derive(Debug, Copy, Clone)]
82 pub enum CheckVertexBufferError {
83     /// The "vertex buffer" usage must be enabled on the buffer.
84     BufferMissingUsage {
85         /// Index of the buffer that is missing usage.
86         num_buffer: usize,
87     },
88 
89     /// The vertex buffer has too many instances.
90     /// When the `multiview` feature is used the maximum amount of instances may be reduced
91     /// because the implementation may use instancing internally to implement `multiview`.
92     TooManyInstances {
93         /// The used amount of instances.
94         instance_count: usize,
95         /// The allowed amount of instances.
96         max_instance_count: usize,
97     },
98 }
99 
100 impl error::Error for CheckVertexBufferError {}
101 
102 impl fmt::Display for CheckVertexBufferError {
103     #[inline]
fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>104     fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
105         write!(
106             fmt,
107             "{}",
108             match *self {
109                 CheckVertexBufferError::BufferMissingUsage { .. } => {
110                     "the vertex buffer usage is missing on a vertex buffer"
111                 }
112                 CheckVertexBufferError::TooManyInstances { .. } => {
113                     "the vertex buffer has too many instances"
114                 }
115             }
116         )
117     }
118 }
119