aboutsummaryrefslogtreecommitdiff
path: root/src/command_buffer/validity/vertex_buffers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/command_buffer/validity/vertex_buffers.rs')
-rw-r--r--src/command_buffer/validity/vertex_buffers.rs118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/command_buffer/validity/vertex_buffers.rs b/src/command_buffer/validity/vertex_buffers.rs
new file mode 100644
index 0000000..9031498
--- /dev/null
+++ b/src/command_buffer/validity/vertex_buffers.rs
@@ -0,0 +1,118 @@
+// Copyright (c) 2017 The vulkano developers
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
+// at your option. All files in the project carrying such
+// notice may not be copied, modified, or distributed except
+// according to those terms.
+
+use std::error;
+use std::fmt;
+
+use crate::buffer::BufferAccess;
+use crate::device::DeviceOwned;
+use crate::pipeline::vertex::VertexSource;
+use crate::pipeline::GraphicsPipelineAbstract;
+use crate::VulkanObject;
+
+/// Checks whether vertex buffers can be bound.
+///
+/// # Panic
+///
+/// - Panics if one of the vertex buffers was not created with the same device as `pipeline`.
+///
+pub fn check_vertex_buffers<GP, V>(
+ pipeline: &GP,
+ vertex_buffers: V,
+) -> Result<CheckVertexBuffer, CheckVertexBufferError>
+where
+ GP: GraphicsPipelineAbstract + DeviceOwned + VertexSource<V>,
+{
+ let (vertex_buffers, vertex_count, instance_count) = pipeline.decode(vertex_buffers);
+
+ for (num, buf) in vertex_buffers.iter().enumerate() {
+ assert_eq!(
+ buf.inner().buffer.device().internal_object(),
+ pipeline.device().internal_object()
+ );
+
+ if !buf.inner().buffer.usage().vertex_buffer {
+ return Err(CheckVertexBufferError::BufferMissingUsage { num_buffer: num });
+ }
+ }
+
+ if let Some(multiview) = pipeline.subpass().render_pass().desc().multiview() {
+ let max_instance_index = pipeline
+ .device()
+ .physical_device()
+ .properties()
+ .max_multiview_instance_index
+ .unwrap_or(0) as usize;
+
+ // vulkano currently always uses `0` as the first instance which means the highest
+ // used index will just be `instance_count - 1`
+ if instance_count > max_instance_index + 1 {
+ return Err(CheckVertexBufferError::TooManyInstances {
+ instance_count,
+ max_instance_count: max_instance_index + 1,
+ });
+ }
+ }
+
+ Ok(CheckVertexBuffer {
+ vertex_buffers,
+ vertex_count: vertex_count as u32,
+ instance_count: instance_count as u32,
+ })
+}
+
+/// Information returned if `check_vertex_buffer` succeeds.
+pub struct CheckVertexBuffer {
+ /// The list of vertex buffers.
+ pub vertex_buffers: Vec<Box<dyn BufferAccess + Send + Sync>>,
+ /// Number of vertices available in the intersection of the buffers.
+ pub vertex_count: u32,
+ /// Number of instances available in the intersection of the buffers.
+ pub instance_count: u32,
+}
+
+/// Error that can happen when checking whether the vertex buffers are valid.
+#[derive(Debug, Copy, Clone)]
+pub enum CheckVertexBufferError {
+ /// The "vertex buffer" usage must be enabled on the buffer.
+ BufferMissingUsage {
+ /// Index of the buffer that is missing usage.
+ num_buffer: usize,
+ },
+
+ /// The vertex buffer has too many instances.
+ /// When the `multiview` feature is used the maximum amount of instances may be reduced
+ /// because the implementation may use instancing internally to implement `multiview`.
+ TooManyInstances {
+ /// The used amount of instances.
+ instance_count: usize,
+ /// The allowed amount of instances.
+ max_instance_count: usize,
+ },
+}
+
+impl error::Error for CheckVertexBufferError {}
+
+impl fmt::Display for CheckVertexBufferError {
+ #[inline]
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ write!(
+ fmt,
+ "{}",
+ match *self {
+ CheckVertexBufferError::BufferMissingUsage { .. } => {
+ "the vertex buffer usage is missing on a vertex buffer"
+ }
+ CheckVertexBufferError::TooManyInstances { .. } => {
+ "the vertex buffer has too many instances"
+ }
+ }
+ )
+ }
+}