rendy_descriptor/
ranges.rs

1use std::{
2    cmp::Ordering,
3    ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign},
4};
5
6pub use gfx_hal::pso::{DescriptorRangeDesc, DescriptorSetLayoutBinding, DescriptorType};
7
8const DESCRIPTOR_TYPES_COUNT: usize = 11;
9
10const DESCRIPTOR_TYPES: [DescriptorType; DESCRIPTOR_TYPES_COUNT] = [
11    DescriptorType::Sampler,
12    DescriptorType::CombinedImageSampler,
13    DescriptorType::SampledImage,
14    DescriptorType::StorageImage,
15    DescriptorType::UniformTexelBuffer,
16    DescriptorType::StorageTexelBuffer,
17    DescriptorType::UniformBuffer,
18    DescriptorType::StorageBuffer,
19    DescriptorType::UniformBufferDynamic,
20    DescriptorType::StorageBufferDynamic,
21    DescriptorType::InputAttachment,
22];
23
24/// Number of descriptors per type.
25#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
26pub struct DescriptorRanges {
27    counts: [u32; DESCRIPTOR_TYPES_COUNT],
28}
29
30impl DescriptorRanges {
31    /// Create new instance without descriptors.
32    pub fn zero() -> Self {
33        DescriptorRanges {
34            counts: [0; DESCRIPTOR_TYPES_COUNT],
35        }
36    }
37
38    /// Add a single layout binding.
39    /// Useful when created with `DescriptorRanges::zero()`.
40    pub fn add_binding(&mut self, binding: DescriptorSetLayoutBinding) {
41        self.counts[binding.ty as usize] += binding.count as u32;
42    }
43
44    /// Iterate through ranges yelding
45    /// descriptor types and their amount.
46    pub fn iter(&self) -> DescriptorRangesIter<'_> {
47        DescriptorRangesIter {
48            counts: &self.counts,
49            index: 0,
50        }
51    }
52
53    /// Read as slice.
54    pub fn counts(&self) -> &[u32] {
55        &self.counts
56    }
57
58    /// Read or write as slice.
59    pub fn counts_mut(&mut self) -> &mut [u32] {
60        &mut self.counts
61    }
62
63    /// Calculate ranges from bindings.
64    pub fn from_bindings(bindings: &[DescriptorSetLayoutBinding]) -> Self {
65        let mut descs = Self::zero();
66
67        for binding in bindings {
68            descs.counts[binding.ty as usize] += binding.count as u32;
69        }
70
71        descs
72    }
73
74    /// Calculate ranges from bindings, specified with an iterator.
75    pub fn from_binding_iter<I>(bindings: I) -> Self
76    where
77        I: Iterator<Item = DescriptorSetLayoutBinding>,
78    {
79        let mut descs = Self::zero();
80
81        for binding in bindings {
82            descs.counts[binding.ty as usize] += binding.count as u32;
83        }
84
85        descs
86    }
87}
88
89impl PartialOrd for DescriptorRanges {
90    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
91        let mut ord = self.counts[0].partial_cmp(&other.counts[0])?;
92        for i in 1..DESCRIPTOR_TYPES_COUNT {
93            match (ord, self.counts[i].partial_cmp(&other.counts[i])?) {
94                (Ordering::Less, Ordering::Greater) | (Ordering::Greater, Ordering::Less) => {
95                    return None;
96                }
97                (Ordering::Equal, new) => ord = new,
98                _ => (),
99            }
100        }
101        Some(ord)
102    }
103}
104
105impl Add for DescriptorRanges {
106    type Output = Self;
107    fn add(mut self, rhs: Self) -> Self {
108        self += rhs;
109        self
110    }
111}
112
113impl AddAssign for DescriptorRanges {
114    fn add_assign(&mut self, rhs: Self) {
115        for i in 0..DESCRIPTOR_TYPES_COUNT {
116            self.counts[i] += rhs.counts[i];
117        }
118    }
119}
120
121impl Sub for DescriptorRanges {
122    type Output = Self;
123    fn sub(mut self, rhs: Self) -> Self {
124        self -= rhs;
125        self
126    }
127}
128
129impl SubAssign for DescriptorRanges {
130    fn sub_assign(&mut self, rhs: Self) {
131        for i in 0..DESCRIPTOR_TYPES_COUNT {
132            self.counts[i] -= rhs.counts[i];
133        }
134    }
135}
136
137impl Mul<u32> for DescriptorRanges {
138    type Output = Self;
139    fn mul(mut self, rhs: u32) -> Self {
140        self *= rhs;
141        self
142    }
143}
144
145impl MulAssign<u32> for DescriptorRanges {
146    fn mul_assign(&mut self, rhs: u32) {
147        for i in 0..DESCRIPTOR_TYPES_COUNT {
148            self.counts[i] *= rhs;
149        }
150    }
151}
152
153impl<'a> IntoIterator for &'a DescriptorRanges {
154    type Item = DescriptorRangeDesc;
155    type IntoIter = DescriptorRangesIter<'a>;
156
157    fn into_iter(self) -> DescriptorRangesIter<'a> {
158        self.iter()
159    }
160}
161
162/// Iterator over descriptor ranges.
163pub struct DescriptorRangesIter<'a> {
164    counts: &'a [u32; DESCRIPTOR_TYPES_COUNT],
165    index: u8,
166}
167
168impl<'a> Iterator for DescriptorRangesIter<'a> {
169    type Item = DescriptorRangeDesc;
170
171    fn next(&mut self) -> Option<DescriptorRangeDesc> {
172        loop {
173            let index = self.index as usize;
174            if index >= DESCRIPTOR_TYPES_COUNT {
175                return None;
176            } else {
177                self.index += 1;
178                if self.counts[index] > 0 {
179                    return Some(DescriptorRangeDesc {
180                        count: self.counts[index] as usize,
181                        ty: DESCRIPTOR_TYPES[index],
182                    });
183                }
184            }
185        }
186    }
187}