rendy_resource/
set.rs

1use {
2    crate::{
3        core::{device_owned, Device, DeviceId},
4        descriptor,
5        escape::Handle,
6    },
7    relevant::Relevant,
8    rendy_core::hal::{device::Device as _, pso::DescriptorSetLayoutBinding, Backend},
9    smallvec::SmallVec,
10};
11
12/// Descriptor set layout info.
13#[derive(Clone, Debug)]
14pub struct DescriptorSetInfo {
15    /// Bindings.
16    pub bindings: Vec<DescriptorSetLayoutBinding>,
17}
18
19impl DescriptorSetInfo {
20    /// Get descriptor ranges of the layout.
21    pub fn ranges(&self) -> descriptor::DescriptorRanges {
22        descriptor::DescriptorRanges::from_bindings(&self.bindings)
23    }
24}
25
26/// Generic descriptor set layout resource wrapper.
27#[derive(Debug)]
28pub struct DescriptorSetLayout<B: Backend> {
29    device: DeviceId,
30    raw: B::DescriptorSetLayout,
31    info: DescriptorSetInfo,
32    relevant: Relevant,
33}
34
35device_owned!(DescriptorSetLayout<B>);
36
37impl<B> DescriptorSetLayout<B>
38where
39    B: Backend,
40{
41    /// Create new descriptor set layout
42    pub unsafe fn create(
43        device: &Device<B>,
44        info: DescriptorSetInfo,
45    ) -> Result<Self, rendy_core::hal::device::OutOfMemory> {
46        let raw = device
47            .create_descriptor_set_layout(&info.bindings, std::iter::empty::<B::Sampler>())?;
48
49        Ok(DescriptorSetLayout {
50            device: device.id(),
51            raw,
52            info,
53            relevant: Relevant,
54        })
55    }
56
57    /// Destroy descriptor set layout resource.
58    pub unsafe fn dispose(self, device: &Device<B>) {
59        self.assert_device_owner(device);
60        device.destroy_descriptor_set_layout(self.raw);
61        self.relevant.dispose();
62    }
63
64    /// Get reference to raw descriptor set layout resource.
65    pub fn raw(&self) -> &B::DescriptorSetLayout {
66        &self.raw
67    }
68
69    /// Get mutable reference to raw descriptor set layout resource.
70    pub unsafe fn raw_mut(&mut self) -> &mut B::DescriptorSetLayout {
71        &mut self.raw
72    }
73
74    /// Get descriptor set layout info.
75    pub fn info(&self) -> &DescriptorSetInfo {
76        &self.info
77    }
78}
79
80/// Generic descriptor set resource wrapper.
81#[derive(Debug)]
82pub struct DescriptorSet<B: Backend> {
83    device: DeviceId,
84    set: descriptor::DescriptorSet<B>,
85    layout: Handle<DescriptorSetLayout<B>>,
86    relevant: Relevant,
87}
88
89device_owned!(DescriptorSet<B>);
90
91impl<B> DescriptorSet<B>
92where
93    B: Backend,
94{
95    /// Create new descriptor set.
96    pub unsafe fn create(
97        device: &Device<B>,
98        allocator: &mut descriptor::DescriptorAllocator<B>,
99        layout: Handle<DescriptorSetLayout<B>>,
100    ) -> Result<Self, rendy_core::hal::device::OutOfMemory> {
101        let mut sets = SmallVec::<[_; 1]>::new();
102
103        allocator.allocate(device, layout.raw(), layout.info().ranges(), 1, &mut sets)?;
104
105        assert_eq!(sets.len() as u32, 1);
106        Ok(DescriptorSet {
107            device: device.id(),
108            set: sets.swap_remove(0),
109            layout: layout.clone(),
110            relevant: Relevant,
111        })
112    }
113
114    /// Create new descriptor sets.
115    pub unsafe fn create_many(
116        device: &Device<B>,
117        allocator: &mut descriptor::DescriptorAllocator<B>,
118        layout: Handle<DescriptorSetLayout<B>>,
119        count: u32,
120        extend: &mut impl Extend<Self>,
121    ) -> Result<(), rendy_core::hal::device::OutOfMemory> {
122        let mut sets = SmallVec::<[_; 32]>::new();
123
124        allocator.allocate(
125            device,
126            layout.raw(),
127            layout.info().ranges(),
128            count,
129            &mut sets,
130        )?;
131
132        assert_eq!(sets.len() as u32, count);
133
134        extend.extend(sets.into_iter().map(|set| DescriptorSet {
135            device: device.id(),
136            set,
137            layout: layout.clone(),
138            relevant: Relevant,
139        }));
140
141        Ok(())
142    }
143
144    /// Destroy descriptor set resource.
145    pub unsafe fn dispose(self, allocator: &mut descriptor::DescriptorAllocator<B>) {
146        allocator.free(Some(self.set));
147        self.relevant.dispose();
148    }
149
150    /// Get reference to raw descriptor set resource.
151    pub fn raw(&self) -> &B::DescriptorSet {
152        self.set.raw()
153    }
154
155    /// Get mutable reference to raw descriptor set resource.
156    pub unsafe fn raw_mut(&mut self) -> &mut B::DescriptorSet {
157        self.set.raw_mut()
158    }
159
160    /// Get layout of descriptor set.
161    pub fn layout(&mut self) -> &Handle<DescriptorSetLayout<B>> {
162        &self.layout
163    }
164}