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