• 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::descriptor_set::layout::DescriptorDescSupersetError;
14 use crate::descriptor_set::DescriptorSetWithOffsets;
15 use crate::pipeline::layout::PipelineLayout;
16 
17 /// Checks whether descriptor sets are compatible with the pipeline.
check_descriptor_sets_validity( pipeline_layout: &PipelineLayout, descriptor_sets: &[DescriptorSetWithOffsets], ) -> Result<(), CheckDescriptorSetsValidityError>18 pub fn check_descriptor_sets_validity(
19     pipeline_layout: &PipelineLayout,
20     descriptor_sets: &[DescriptorSetWithOffsets],
21 ) -> Result<(), CheckDescriptorSetsValidityError> {
22     // What's important is not that the pipeline layout and the descriptor sets *match*. Instead
23     // what's important is that the descriptor sets are a superset of the pipeline layout. It's not
24     // a problem if the descriptor sets provide more elements than expected.
25 
26     for (set_num, set) in pipeline_layout.descriptor_set_layouts().iter().enumerate() {
27         for (binding_num, pipeline_desc) in
28             (0..set.num_bindings()).filter_map(|i| set.descriptor(i).map(|d| (i, d)))
29         {
30             let set_desc = descriptor_sets
31                 .get(set_num)
32                 .and_then(|so| so.as_ref().0.layout().descriptor(binding_num));
33 
34             let set_desc = match set_desc {
35                 Some(s) => s,
36                 None => {
37                     return Err(CheckDescriptorSetsValidityError::MissingDescriptor {
38                         set_num: set_num,
39                         binding_num: binding_num,
40                     })
41                 }
42             };
43 
44             if let Err(err) = set_desc.ensure_superset_of(&pipeline_desc) {
45                 return Err(CheckDescriptorSetsValidityError::IncompatibleDescriptor {
46                     error: err,
47                     set_num: set_num,
48                     binding_num: binding_num,
49                 });
50             }
51         }
52     }
53 
54     Ok(())
55 }
56 
57 /// Error that can happen when checking descriptor sets validity.
58 #[derive(Debug, Clone)]
59 pub enum CheckDescriptorSetsValidityError {
60     /// A descriptor is missing in the descriptor sets that were provided.
61     MissingDescriptor {
62         /// The index of the set of the descriptor.
63         set_num: usize,
64         /// The binding number of the descriptor.
65         binding_num: usize,
66     },
67 
68     /// A descriptor in the provided sets is not compatible with what is expected.
69     IncompatibleDescriptor {
70         /// The reason why the two descriptors aren't compatible.
71         error: DescriptorDescSupersetError,
72         /// The index of the set of the descriptor.
73         set_num: usize,
74         /// The binding number of the descriptor.
75         binding_num: usize,
76     },
77 }
78 
79 impl error::Error for CheckDescriptorSetsValidityError {
80     #[inline]
source(&self) -> Option<&(dyn error::Error + 'static)>81     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
82         match *self {
83             CheckDescriptorSetsValidityError::IncompatibleDescriptor { ref error, .. } => {
84                 Some(error)
85             }
86             _ => None,
87         }
88     }
89 }
90 
91 impl fmt::Display for CheckDescriptorSetsValidityError {
92     #[inline]
fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>93     fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
94         write!(
95             fmt,
96             "{}",
97             match *self {
98                 CheckDescriptorSetsValidityError::MissingDescriptor { .. } => {
99                     "a descriptor is missing in the descriptor sets that were provided"
100                 }
101                 CheckDescriptorSetsValidityError::IncompatibleDescriptor { .. } => {
102                     "a descriptor in the provided sets is not compatible with what is expected"
103                 }
104             }
105         )
106     }
107 }
108 
109 // TODO: tests
110