// Copyright (c) 2017 The vulkano developers // Licensed under the Apache License, Version 2.0 // or the MIT // license , // 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( pipeline: &GP, vertex_buffers: V, ) -> Result where GP: GraphicsPipelineAbstract + DeviceOwned + VertexSource, { 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>, /// 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" } } ) } }