1use {
4 super::{Lease, Pool},
5 crate::driver::{
6 DriverError,
7 accel_struct::{
8 AccelerationStructure, AccelerationStructureInfo, AccelerationStructureInfoBuilder,
9 },
10 buffer::{Buffer, BufferInfo, BufferInfoBuilder},
11 image::{Image, ImageInfo, ImageInfoBuilder},
12 },
13 log::debug,
14 std::{
15 ops::{Deref, DerefMut},
16 sync::{Arc, Weak},
17 },
18};
19
20pub trait Alias<I, T> {
22 fn alias(&mut self, info: I) -> Result<Arc<Lease<T>>, DriverError>;
24}
25
26macro_rules! alias_builder {
28 ($info:ident => $item:ident) => {
29 paste::paste! {
30 impl<T> Alias<[<$info Builder>], $item> for T where T: Alias<$info, $item> {
31 fn alias(&mut self, builder: [<$info Builder>]) -> Result<Arc<Lease<$item>>, DriverError> {
32 let info = builder.build();
33
34 self.alias(info)
35 }
36 }
37 }
38 };
39}
40
41alias_builder!(AccelerationStructureInfo => AccelerationStructure);
42alias_builder!(BufferInfo => Buffer);
43alias_builder!(ImageInfo => Image);
44
45pub struct AliasPool<T> {
67 accel_structs: Vec<(
68 AccelerationStructureInfo,
69 Weak<Lease<AccelerationStructure>>,
70 )>,
71 buffers: Vec<(BufferInfo, Weak<Lease<Buffer>>)>,
72 images: Vec<(ImageInfo, Weak<Lease<Image>>)>,
73 pool: T,
74}
75
76impl<T> AliasPool<T> {
77 pub fn new(pool: T) -> Self {
79 Self {
80 accel_structs: Default::default(),
81 buffers: Default::default(),
82 images: Default::default(),
83 pool,
84 }
85 }
86}
87
88macro_rules! lease_pass_through {
90 ($info:ident => $item:ident) => {
91 paste::paste! {
92 impl<T> Pool<$info, $item> for AliasPool<T> where T: Pool<$info, $item> {
93 fn lease(&mut self, info: $info) -> Result<Lease<$item>, DriverError> {
94 self.pool.lease(info)
95 }
96 }
97 }
98 };
99}
100
101lease_pass_through!(AccelerationStructureInfo => AccelerationStructure);
102lease_pass_through!(BufferInfo => Buffer);
103lease_pass_through!(ImageInfo => Image);
104
105impl<T> Alias<AccelerationStructureInfo, AccelerationStructure> for AliasPool<T>
106where
107 T: Pool<AccelerationStructureInfo, AccelerationStructure>,
108{
109 fn alias(
110 &mut self,
111 info: AccelerationStructureInfo,
112 ) -> Result<Arc<Lease<AccelerationStructure>>, DriverError> {
113 self.accel_structs
114 .retain(|(_, item)| item.strong_count() > 0);
115
116 {
117 profiling::scope!("check aliases");
118
119 for (item_info, item) in &self.accel_structs {
120 if item_info.ty == info.ty && item_info.size >= info.size {
121 if let Some(item) = item.upgrade() {
122 return Ok(item);
123 } else {
124 break;
125 }
126 }
127 }
128 }
129
130 debug!("Leasing new {}", stringify!(AccelerationStructure));
131
132 let item = Arc::new(self.pool.lease(info)?);
133 self.accel_structs.push((info, Arc::downgrade(&item)));
134
135 Ok(item)
136 }
137}
138
139impl<T> Alias<BufferInfo, Buffer> for AliasPool<T>
140where
141 T: Pool<BufferInfo, Buffer>,
142{
143 fn alias(&mut self, info: BufferInfo) -> Result<Arc<Lease<Buffer>>, DriverError> {
144 self.buffers.retain(|(_, item)| item.strong_count() > 0);
145
146 {
147 profiling::scope!("check aliases");
148
149 for (item_info, item) in &self.buffers {
150 if item_info.mappable == info.mappable
151 && item_info.alignment >= info.alignment
152 && item_info.size >= info.size
153 && item_info.usage.contains(info.usage)
154 {
155 if let Some(item) = item.upgrade() {
156 return Ok(item);
157 } else {
158 break;
159 }
160 }
161 }
162 }
163
164 debug!("Leasing new {}", stringify!(Buffer));
165
166 let item = Arc::new(self.pool.lease(info)?);
167 self.buffers.push((info, Arc::downgrade(&item)));
168
169 Ok(item)
170 }
171}
172
173impl<T> Alias<ImageInfo, Image> for AliasPool<T>
174where
175 T: Pool<ImageInfo, Image>,
176{
177 fn alias(&mut self, info: ImageInfo) -> Result<Arc<Lease<Image>>, DriverError> {
178 self.images.retain(|(_, item)| item.strong_count() > 0);
179
180 {
181 profiling::scope!("check aliases");
182
183 for (item_info, item) in &self.images {
184 if item_info.array_layer_count == info.array_layer_count
185 && item_info.depth == info.depth
186 && item_info.fmt == info.fmt
187 && item_info.height == info.height
188 && item_info.mip_level_count == info.mip_level_count
189 && item_info.sample_count == info.sample_count
190 && item_info.tiling == info.tiling
191 && item_info.ty == info.ty
192 && item_info.width == info.width
193 && item_info.flags.contains(info.flags)
194 && item_info.usage.contains(info.usage)
195 {
196 if let Some(item) = item.upgrade() {
197 return Ok(item);
198 } else {
199 break;
200 }
201 }
202 }
203 }
204
205 debug!("Leasing new {}", stringify!(Image));
206
207 let item = Arc::new(self.pool.lease(info)?);
208 self.images.push((info, Arc::downgrade(&item)));
209
210 Ok(item)
211 }
212}
213
214impl<T> Deref for AliasPool<T> {
215 type Target = T;
216
217 fn deref(&self) -> &Self::Target {
218 &self.pool
219 }
220}
221
222impl<T> DerefMut for AliasPool<T> {
223 fn deref_mut(&mut self) -> &mut Self::Target {
224 &mut self.pool
225 }
226}