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#[derive(Clone, Debug)]
14pub struct DescriptorSetInfo {
15 pub bindings: Vec<DescriptorSetLayoutBinding>,
17}
18
19impl DescriptorSetInfo {
20 pub fn ranges(&self) -> descriptor::DescriptorRanges {
22 descriptor::DescriptorRanges::from_bindings(&self.bindings)
23 }
24}
25
26#[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 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 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 pub fn raw(&self) -> &B::DescriptorSetLayout {
66 &self.raw
67 }
68
69 pub unsafe fn raw_mut(&mut self) -> &mut B::DescriptorSetLayout {
71 &mut self.raw
72 }
73
74 pub fn info(&self) -> &DescriptorSetInfo {
76 &self.info
77 }
78}
79
80#[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 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 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 pub unsafe fn dispose(self, allocator: &mut descriptor::DescriptorAllocator<B>) {
146 allocator.free(Some(self.set));
147 self.relevant.dispose();
148 }
149
150 pub fn raw(&self) -> &B::DescriptorSet {
152 self.set.raw()
153 }
154
155 pub unsafe fn raw_mut(&mut self) -> &mut B::DescriptorSet {
157 self.set.raw_mut()
158 }
159
160 pub fn layout(&mut self) -> &Handle<DescriptorSetLayout<B>> {
162 &self.layout
163 }
164}