| // 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::Device; |
| use crate::device::DeviceOwned; |
| use crate::VulkanObject; |
| |
| /// Checks whether a fill buffer command is valid. |
| /// |
| /// # Panic |
| /// |
| /// - Panics if the buffer not created with `device`. |
| /// |
| pub fn check_fill_buffer<B>(device: &Device, buffer: &B) -> Result<(), CheckFillBufferError> |
| where |
| B: ?Sized + BufferAccess, |
| { |
| assert_eq!( |
| buffer.inner().buffer.device().internal_object(), |
| device.internal_object() |
| ); |
| |
| if !buffer.inner().buffer.usage().transfer_destination { |
| return Err(CheckFillBufferError::BufferMissingUsage); |
| } |
| |
| if buffer.inner().offset % 4 != 0 { |
| return Err(CheckFillBufferError::WrongAlignment); |
| } |
| |
| Ok(()) |
| } |
| |
| /// Error that can happen when attempting to add a `fill_buffer` command. |
| #[derive(Debug, Copy, Clone)] |
| pub enum CheckFillBufferError { |
| /// The "transfer destination" usage must be enabled on the buffer. |
| BufferMissingUsage, |
| /// The data or size must be 4-bytes aligned. |
| WrongAlignment, |
| } |
| |
| impl error::Error for CheckFillBufferError {} |
| |
| impl fmt::Display for CheckFillBufferError { |
| #[inline] |
| fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { |
| write!( |
| fmt, |
| "{}", |
| match *self { |
| CheckFillBufferError::BufferMissingUsage => { |
| "the transfer destination usage must be enabled on the buffer" |
| } |
| CheckFillBufferError::WrongAlignment => |
| "the offset or size are not aligned to 4 bytes", |
| } |
| ) |
| } |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use super::*; |
| use crate::buffer::BufferUsage; |
| use crate::buffer::CpuAccessibleBuffer; |
| |
| #[test] |
| fn missing_usage() { |
| let (device, queue) = gfx_dev_and_queue!(); |
| let buffer = CpuAccessibleBuffer::from_data( |
| device.clone(), |
| BufferUsage::vertex_buffer(), |
| false, |
| 0u32, |
| ) |
| .unwrap(); |
| |
| match check_fill_buffer(&device, &buffer) { |
| Err(CheckFillBufferError::BufferMissingUsage) => (), |
| _ => panic!(), |
| } |
| } |
| |
| #[test] |
| fn wrong_device() { |
| let (dev1, queue) = gfx_dev_and_queue!(); |
| let (dev2, _) = gfx_dev_and_queue!(); |
| let buffer = CpuAccessibleBuffer::from_data(dev1, BufferUsage::all(), false, 0u32).unwrap(); |
| |
| assert_should_panic!({ |
| let _ = check_fill_buffer(&dev2, &buffer); |
| }); |
| } |
| } |