• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2016 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 crate::buffer::TypedBufferAccess;
11 use crate::device::Device;
12 use crate::device::DeviceOwned;
13 use crate::DeviceSize;
14 use crate::VulkanObject;
15 use std::cmp;
16 use std::error;
17 use std::fmt;
18 
19 /// Checks whether a copy buffer command is valid.
20 ///
21 /// # Panic
22 ///
23 /// - Panics if the source and destination were not created with `device`.
24 ///
check_copy_buffer<S, D, T>( device: &Device, source: &S, destination: &D, ) -> Result<CheckCopyBuffer, CheckCopyBufferError> where S: ?Sized + TypedBufferAccess<Content = T>, D: ?Sized + TypedBufferAccess<Content = T>, T: ?Sized,25 pub fn check_copy_buffer<S, D, T>(
26     device: &Device,
27     source: &S,
28     destination: &D,
29 ) -> Result<CheckCopyBuffer, CheckCopyBufferError>
30 where
31     S: ?Sized + TypedBufferAccess<Content = T>,
32     D: ?Sized + TypedBufferAccess<Content = T>,
33     T: ?Sized,
34 {
35     assert_eq!(
36         source.inner().buffer.device().internal_object(),
37         device.internal_object()
38     );
39     assert_eq!(
40         destination.inner().buffer.device().internal_object(),
41         device.internal_object()
42     );
43 
44     if !source.inner().buffer.usage().transfer_source {
45         return Err(CheckCopyBufferError::SourceMissingTransferUsage);
46     }
47 
48     if !destination.inner().buffer.usage().transfer_destination {
49         return Err(CheckCopyBufferError::DestinationMissingTransferUsage);
50     }
51 
52     let copy_size = cmp::min(source.size(), destination.size());
53 
54     if source.conflict_key() == destination.conflict_key() {
55         return Err(CheckCopyBufferError::OverlappingRanges);
56     } else {
57         debug_assert!(destination.conflict_key() != source.conflict_key());
58     }
59 
60     Ok(CheckCopyBuffer { copy_size })
61 }
62 
63 /// Information returned if `check_copy_buffer` succeeds.
64 pub struct CheckCopyBuffer {
65     /// Size of the transfer in bytes.
66     ///
67     /// If the size of the source and destination are not equal, then the value is equal to the
68     /// smallest of the two.
69     pub copy_size: DeviceSize,
70 }
71 
72 /// Error that can happen from `check_copy_buffer`.
73 #[derive(Debug, Copy, Clone)]
74 pub enum CheckCopyBufferError {
75     /// The source buffer is missing the transfer source usage.
76     SourceMissingTransferUsage,
77     /// The destination buffer is missing the transfer destination usage.
78     DestinationMissingTransferUsage,
79     /// The source and destination are overlapping.
80     OverlappingRanges,
81 }
82 
83 impl error::Error for CheckCopyBufferError {}
84 
85 impl fmt::Display for CheckCopyBufferError {
86     #[inline]
fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>87     fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
88         write!(
89             fmt,
90             "{}",
91             match *self {
92                 CheckCopyBufferError::SourceMissingTransferUsage => {
93                     "the source buffer is missing the transfer source usage"
94                 }
95                 CheckCopyBufferError::DestinationMissingTransferUsage => {
96                     "the destination buffer is missing the transfer destination usage"
97                 }
98                 CheckCopyBufferError::OverlappingRanges =>
99                     "the source and destination are overlapping",
100             }
101         )
102     }
103 }
104