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::Device;
15 use crate::device::DeviceOwned;
16 use crate::VulkanObject;
17
18 /// Checks whether a fill buffer command is valid.
19 ///
20 /// # Panic
21 ///
22 /// - Panics if the buffer not created with `device`.
23 ///
check_fill_buffer<B>(device: &Device, buffer: &B) -> Result<(), CheckFillBufferError> where B: ?Sized + BufferAccess,24 pub fn check_fill_buffer<B>(device: &Device, buffer: &B) -> Result<(), CheckFillBufferError>
25 where
26 B: ?Sized + BufferAccess,
27 {
28 assert_eq!(
29 buffer.inner().buffer.device().internal_object(),
30 device.internal_object()
31 );
32
33 if !buffer.inner().buffer.usage().transfer_destination {
34 return Err(CheckFillBufferError::BufferMissingUsage);
35 }
36
37 if buffer.inner().offset % 4 != 0 {
38 return Err(CheckFillBufferError::WrongAlignment);
39 }
40
41 Ok(())
42 }
43
44 /// Error that can happen when attempting to add a `fill_buffer` command.
45 #[derive(Debug, Copy, Clone)]
46 pub enum CheckFillBufferError {
47 /// The "transfer destination" usage must be enabled on the buffer.
48 BufferMissingUsage,
49 /// The data or size must be 4-bytes aligned.
50 WrongAlignment,
51 }
52
53 impl error::Error for CheckFillBufferError {}
54
55 impl fmt::Display for CheckFillBufferError {
56 #[inline]
fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>57 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
58 write!(
59 fmt,
60 "{}",
61 match *self {
62 CheckFillBufferError::BufferMissingUsage => {
63 "the transfer destination usage must be enabled on the buffer"
64 }
65 CheckFillBufferError::WrongAlignment =>
66 "the offset or size are not aligned to 4 bytes",
67 }
68 )
69 }
70 }
71
72 #[cfg(test)]
73 mod tests {
74 use super::*;
75 use crate::buffer::BufferUsage;
76 use crate::buffer::CpuAccessibleBuffer;
77
78 #[test]
missing_usage()79 fn missing_usage() {
80 let (device, queue) = gfx_dev_and_queue!();
81 let buffer = CpuAccessibleBuffer::from_data(
82 device.clone(),
83 BufferUsage::vertex_buffer(),
84 false,
85 0u32,
86 )
87 .unwrap();
88
89 match check_fill_buffer(&device, &buffer) {
90 Err(CheckFillBufferError::BufferMissingUsage) => (),
91 _ => panic!(),
92 }
93 }
94
95 #[test]
wrong_device()96 fn wrong_device() {
97 let (dev1, queue) = gfx_dev_and_queue!();
98 let (dev2, _) = gfx_dev_and_queue!();
99 let buffer = CpuAccessibleBuffer::from_data(dev1, BufferUsage::all(), false, 0u32).unwrap();
100
101 assert_should_panic!({
102 let _ = check_fill_buffer(&dev2, &buffer);
103 });
104 }
105 }
106