• 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::buffer::TypedBufferAccess;
15 use crate::device::Device;
16 use crate::device::DeviceOwned;
17 use crate::pipeline::input_assembly::Index;
18 use crate::VulkanObject;
19 
20 /// Checks whether an index buffer can be bound.
21 ///
22 /// # Panic
23 ///
24 /// - Panics if the buffer was not created with `device`.
25 ///
check_index_buffer<B, I>( device: &Device, buffer: &B, ) -> Result<CheckIndexBuffer, CheckIndexBufferError> where B: ?Sized + BufferAccess + TypedBufferAccess<Content = [I]>, I: Index,26 pub fn check_index_buffer<B, I>(
27     device: &Device,
28     buffer: &B,
29 ) -> Result<CheckIndexBuffer, CheckIndexBufferError>
30 where
31     B: ?Sized + BufferAccess + TypedBufferAccess<Content = [I]>,
32     I: Index,
33 {
34     assert_eq!(
35         buffer.inner().buffer.device().internal_object(),
36         device.internal_object()
37     );
38 
39     if !buffer.inner().buffer.usage().index_buffer {
40         return Err(CheckIndexBufferError::BufferMissingUsage);
41     }
42 
43     // TODO: The sum of offset and the address of the range of VkDeviceMemory object that is
44     //       backing buffer, must be a multiple of the type indicated by indexType
45 
46     // TODO: full_draw_index_uint32 feature
47 
48     Ok(CheckIndexBuffer {
49         num_indices: buffer.len() as u32,
50     })
51 }
52 
53 /// Information returned if `check_index_buffer` succeeds.
54 pub struct CheckIndexBuffer {
55     /// Number of indices in the index buffer.
56     pub num_indices: u32,
57 }
58 
59 /// Error that can happen when checking whether binding an index buffer is valid.
60 #[derive(Debug, Copy, Clone)]
61 pub enum CheckIndexBufferError {
62     /// The "index buffer" usage must be enabled on the index buffer.
63     BufferMissingUsage,
64     /// The data or size must be 4-bytes aligned.
65     WrongAlignment,
66     /// The type of the indices is not supported by the device.
67     UnsupportIndexType,
68 }
69 
70 impl error::Error for CheckIndexBufferError {}
71 
72 impl fmt::Display for CheckIndexBufferError {
73     #[inline]
fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>74     fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
75         write!(
76             fmt,
77             "{}",
78             match *self {
79                 CheckIndexBufferError::BufferMissingUsage => {
80                     "the index buffer usage must be enabled on the index buffer"
81                 }
82                 CheckIndexBufferError::WrongAlignment => {
83                     "the sum of offset and the address of the range of VkDeviceMemory object that is \
84                  backing buffer, must be a multiple of the type indicated by indexType"
85                 }
86                 CheckIndexBufferError::UnsupportIndexType => {
87                     "the type of the indices is not supported by the device"
88                 }
89             }
90         )
91     }
92 }
93 
94 #[cfg(test)]
95 mod tests {
96     use super::*;
97     use crate::buffer::BufferUsage;
98     use crate::buffer::CpuAccessibleBuffer;
99 
100     #[test]
num_indices()101     fn num_indices() {
102         let (device, queue) = gfx_dev_and_queue!();
103         let buffer = CpuAccessibleBuffer::from_iter(
104             device.clone(),
105             BufferUsage::index_buffer(),
106             false,
107             0..500u32,
108         )
109         .unwrap();
110 
111         match check_index_buffer(&device, &buffer) {
112             Ok(CheckIndexBuffer { num_indices }) => {
113                 assert_eq!(num_indices, 500);
114             }
115             _ => panic!(),
116         }
117     }
118 
119     #[test]
missing_usage()120     fn missing_usage() {
121         let (device, queue) = gfx_dev_and_queue!();
122         let buffer = CpuAccessibleBuffer::from_iter(
123             device.clone(),
124             BufferUsage::vertex_buffer(),
125             false,
126             0..500u32,
127         )
128         .unwrap();
129 
130         match check_index_buffer(&device, &buffer) {
131             Err(CheckIndexBufferError::BufferMissingUsage) => (),
132             _ => panic!(),
133         }
134     }
135 
136     #[test]
wrong_device()137     fn wrong_device() {
138         let (dev1, queue) = gfx_dev_and_queue!();
139         let (dev2, _) = gfx_dev_and_queue!();
140 
141         let buffer =
142             CpuAccessibleBuffer::from_iter(dev1, BufferUsage::all(), false, 0..500u32).unwrap();
143 
144         assert_should_panic!({
145             let _ = check_index_buffer(&dev2, &buffer);
146         });
147     }
148 }
149