Check the descriptor sets compatibility when drawing
use std::error;
use std::fmt;
-use descriptor::pipeline_layout::PipelineLayoutAbstract;
+use descriptor::descriptor_set::DescriptorSetsCollection;
+use descriptor::pipeline_layout::PipelineLayoutDesc;
/// Checks whether descriptor sets are compatible with the pipeline.
pub fn check_descriptor_sets_validity<Pl, D>(pipeline: &Pl, descriptor_sets: &D)
-> Result<(), CheckDescriptorSetsValidityError>
- where Pl: ?Sized + PipelineLayoutAbstract,
- D: ?Sized,
+ where Pl: ?Sized + PipelineLayoutDesc,
+ D: ?Sized + DescriptorSetsCollection,
{
- // TODO: implement
+ // What's important is not that the pipeline layout and the descriptor sets *match*. Instead
+ // what's important is that the descriptor sets are a superset of the pipeline layout. It's not
+ // a problem if the descriptor sets provide more elements than expected.
+
+ for set_num in 0 .. pipeline.num_sets() {
+ for binding_num in 0 .. pipeline.num_bindings_in_set(set_num).unwrap_or(0) {
+ let set_desc = descriptor_sets.descriptor(set_num, binding_num);
+ let pipeline_desc = pipeline.descriptor(set_num, binding_num);
+
+ let (set_desc, pipeline_desc) = match (set_desc, pipeline_desc) {
+ (Some(s), Some(p)) => (s, p),
+ (None, Some(_)) => return Err(CheckDescriptorSetsValidityError::MissingDescriptor {
+ set_num: set_num,
+ binding_num: binding_num,
+ }),
+ (Some(_), None) => continue,
+ (None, None) => continue,
+ };
+
+ if !set_desc.is_superset_of(&pipeline_desc) {
+ return Err(CheckDescriptorSetsValidityError::IncompatibleDescriptor {
+ set_num: set_num,
+ binding_num: binding_num,
+ });
+ }
+ }
+ }
Ok(())
}
@@ -26,16 +53,32 @@ pub fn check_descriptor_sets_validity<Pl, D>(pipeline: &Pl, descriptor_sets: &D)
/// Error that can happen when checking descriptor sets validity.
#[derive(Debug, Copy, Clone)]
pub enum CheckDescriptorSetsValidityError {
- /// The descriptor sets are incompatible with the pipeline layout.
- IncompatibleDescriptorSets,
+ /// A descriptor is missing in the descriptor sets that were provided.
+ MissingDescriptor {
+ /// The index of the set of the descriptor.
+ set_num: usize,
+ /// The binding number of the descriptor.
+ binding_num: usize,
+ },
+
+ /// A descriptor in the provided sets is not compatible with what is expected.
+ IncompatibleDescriptor {
+ /// The index of the set of the descriptor.
+ set_num: usize,
+ /// The binding number of the descriptor.
+ binding_num: usize,
+ },
}
impl error::Error for CheckDescriptorSetsValidityError {
#[inline]
fn description(&self) -> &str {
match *self {
- CheckDescriptorSetsValidityError::IncompatibleDescriptorSets => {
- "the descriptor sets are incompatible with the pipeline layout"
+ CheckDescriptorSetsValidityError::MissingDescriptor { .. } => {
+ "a descriptor is missing in the descriptor sets that were provided"
+ },
+ CheckDescriptorSetsValidityError::IncompatibleDescriptor { .. } => {
+ "a descriptor in the provided sets is not compatible with what is expected"
},
}
}
@@ -47,3 +90,5 @@ impl fmt::Display for CheckDescriptorSetsValidityError {
write!(fmt, "{}", error::Error::description(self))
}
}
+
+// TODO: tests
