// Copyright (c) 2016 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 crate::buffer::TypedBufferAccess; use crate::device::Device; use crate::device::DeviceOwned; use crate::DeviceSize; use crate::VulkanObject; use std::cmp; use std::error; use std::fmt; /// Checks whether a copy buffer command is valid. /// /// # Panic /// /// - Panics if the source and destination were not created with `device`. /// pub fn check_copy_buffer( device: &Device, source: &S, destination: &D, ) -> Result where S: ?Sized + TypedBufferAccess, D: ?Sized + TypedBufferAccess, T: ?Sized, { assert_eq!( source.inner().buffer.device().internal_object(), device.internal_object() ); assert_eq!( destination.inner().buffer.device().internal_object(), device.internal_object() ); if !source.inner().buffer.usage().transfer_source { return Err(CheckCopyBufferError::SourceMissingTransferUsage); } if !destination.inner().buffer.usage().transfer_destination { return Err(CheckCopyBufferError::DestinationMissingTransferUsage); } let copy_size = cmp::min(source.size(), destination.size()); if source.conflict_key() == destination.conflict_key() { return Err(CheckCopyBufferError::OverlappingRanges); } else { debug_assert!(destination.conflict_key() != source.conflict_key()); } Ok(CheckCopyBuffer { copy_size }) } /// Information returned if `check_copy_buffer` succeeds. pub struct CheckCopyBuffer { /// Size of the transfer in bytes. /// /// If the size of the source and destination are not equal, then the value is equal to the /// smallest of the two. pub copy_size: DeviceSize, } /// Error that can happen from `check_copy_buffer`. #[derive(Debug, Copy, Clone)] pub enum CheckCopyBufferError { /// The source buffer is missing the transfer source usage. SourceMissingTransferUsage, /// The destination buffer is missing the transfer destination usage. DestinationMissingTransferUsage, /// The source and destination are overlapping. OverlappingRanges, } impl error::Error for CheckCopyBufferError {} impl fmt::Display for CheckCopyBufferError { #[inline] fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!( fmt, "{}", match *self { CheckCopyBufferError::SourceMissingTransferUsage => { "the source buffer is missing the transfer source usage" } CheckCopyBufferError::DestinationMissingTransferUsage => { "the destination buffer is missing the transfer destination usage" } CheckCopyBufferError::OverlappingRanges => "the source and destination are overlapping", } ) } }