1use {
2 super::{
3 AccelerationStructureLeaseNode, AccelerationStructureNode, BufferLeaseNode, BufferNode,
4 ImageLeaseNode, ImageNode, RenderGraph,
5 },
6 crate::{
7 driver::{
8 accel_struct::AccelerationStructure, buffer::Buffer, image::Image,
9 swapchain::SwapchainImage,
10 },
11 pool::Lease,
12 },
13 std::{fmt::Debug, sync::Arc},
14};
15
16pub trait Bind<Graph, Node> {
64 fn bind(self, graph: Graph) -> Node;
68}
69
70#[derive(Debug)]
71pub enum Binding {
72 AccelerationStructure(Arc<AccelerationStructure>, bool),
73 AccelerationStructureLease(Arc<Lease<AccelerationStructure>>, bool),
74 Buffer(Arc<Buffer>, bool),
75 BufferLease(Arc<Lease<Buffer>>, bool),
76 Image(Arc<Image>, bool),
77 ImageLease(Arc<Lease<Image>>, bool),
78 SwapchainImage(Box<SwapchainImage>, bool),
79}
80
81impl Binding {
82 pub(super) fn as_driver_acceleration_structure(&self) -> Option<&AccelerationStructure> {
83 Some(match self {
84 Self::AccelerationStructure(binding, _) => binding,
85 Self::AccelerationStructureLease(binding, _) => binding,
86 _ => return None,
87 })
88 }
89
90 pub(super) fn as_driver_buffer(&self) -> Option<&Buffer> {
91 Some(match self {
92 Self::Buffer(binding, _) => binding,
93 Self::BufferLease(binding, _) => binding,
94 _ => return None,
95 })
96 }
97
98 pub(super) fn as_driver_image(&self) -> Option<&Image> {
99 Some(match self {
100 Self::Image(binding, _) => binding,
101 Self::ImageLease(binding, _) => binding,
102 Self::SwapchainImage(binding, _) => binding,
103 _ => return None,
104 })
105 }
106
107 pub(super) fn is_bound(&self) -> bool {
108 match self {
109 Self::AccelerationStructure(_, is_bound) => *is_bound,
110 Self::AccelerationStructureLease(_, is_bound) => *is_bound,
111 Self::Buffer(_, is_bound) => *is_bound,
112 Self::BufferLease(_, is_bound) => *is_bound,
113 Self::Image(_, is_bound) => *is_bound,
114 Self::ImageLease(_, is_bound) => *is_bound,
115 Self::SwapchainImage(_, is_bound) => *is_bound,
116 }
117 }
118
119 pub(super) fn unbind(&mut self) {
120 *match self {
121 Self::AccelerationStructure(_, is_bound) => is_bound,
122 Self::AccelerationStructureLease(_, is_bound) => is_bound,
123 Self::Buffer(_, is_bound) => is_bound,
124 Self::BufferLease(_, is_bound) => is_bound,
125 Self::Image(_, is_bound) => is_bound,
126 Self::ImageLease(_, is_bound) => is_bound,
127 Self::SwapchainImage(_, is_bound) => is_bound,
128 } = false;
129 }
130}
131
132macro_rules! bind {
133 ($name:ident) => {
134 paste::paste! {
135 impl Bind<&mut RenderGraph, [<$name Node>]> for $name {
136 #[profiling::function]
137 fn bind(self, graph: &mut RenderGraph) -> [<$name Node>] {
138 let res = [<$name Node>]::new(graph.bindings.len());
142 let binding = Binding::$name(Arc::new(self), true);
143 graph.bindings.push(binding);
144
145 res
146 }
147 }
148
149 impl<'a> Bind<&mut RenderGraph, [<$name Node>]> for &'a Arc<$name> {
150 fn bind(self, graph: &mut RenderGraph) -> [<$name Node>] {
151 Arc::clone(self).bind(graph)
155 }
156 }
157
158 impl Bind<&mut RenderGraph, [<$name Node>]> for Arc<$name> {
159 #[profiling::function]
160 fn bind(self, graph: &mut RenderGraph) -> [<$name Node>] {
161 for (idx, existing_binding) in graph.bindings.iter_mut().enumerate() {
167 if let Some((existing_binding, is_bound)) = existing_binding.[<as_ $name:snake _mut>]() {
168 if Arc::ptr_eq(existing_binding, &self) {
169 *is_bound = true;
170
171 return [<$name Node>]::new(idx);
172 }
173 }
174 }
175
176 let res = [<$name Node>]::new(graph.bindings.len());
178 let binding = Binding::$name(self, true);
179 graph.bindings.push(binding);
180
181 res
182 }
183 }
184
185 impl Binding {
186 pub(super) fn [<as_ $name:snake>](&self) -> Option<&Arc<$name>> {
187 if let Self::$name(binding, _) = self {
188 Some(&binding)
189 } else {
190 None
191 }
192 }
193
194 pub(super) fn [<as_ $name:snake _mut>](&mut self) -> Option<(&mut Arc<$name>, &mut bool)> {
195 if let Self::$name(binding, is_bound) = self {
196 Some((binding, is_bound))
197 } else {
198 None
199 }
200 }
201 }
202 }
203 };
204}
205
206bind!(AccelerationStructure);
207bind!(Image);
208bind!(Buffer);
209
210macro_rules! bind_lease {
211 ($name:ident) => {
212 paste::paste! {
213 impl Bind<&mut RenderGraph, [<$name LeaseNode>]> for Lease<$name> {
214 #[profiling::function]
215 fn bind(self, graph: &mut RenderGraph) -> [<$name LeaseNode>] {
216 let res = [<$name LeaseNode>]::new(graph.bindings.len());
221 let binding = Binding::[<$name Lease>](Arc::new(self), true);
222 graph.bindings.push(binding);
223
224 res
225 }
226 }
227
228 impl<'a> Bind<&mut RenderGraph, [<$name LeaseNode>]> for &'a Arc<Lease<$name>> {
229 fn bind(self, graph: &mut RenderGraph) -> [<$name LeaseNode>] {
230 Arc::clone(self).bind(graph)
234 }
235 }
236
237 impl Bind<&mut RenderGraph, [<$name LeaseNode>]> for Arc<Lease<$name>> {
238 #[profiling::function]
239 fn bind(self, graph: &mut RenderGraph) -> [<$name LeaseNode>] {
240 for (idx, existing_binding) in graph.bindings.iter_mut().enumerate() {
246 if let Some((existing_binding, is_bound)) = existing_binding.[<as_ $name:snake _lease_mut>]() {
247 if Arc::ptr_eq(existing_binding, &self) {
248 *is_bound = true;
249
250 return [<$name LeaseNode>]::new(idx);
251 }
252 }
253 }
254
255 let res = [<$name LeaseNode>]::new(graph.bindings.len());
257 let binding = Binding::[<$name Lease>](self, true);
258 graph.bindings.push(binding);
259
260 res
261 }
262 }
263
264 impl Binding {
265 pub(super) fn [<as_ $name:snake _lease>](&self) -> Option<&Arc<Lease<$name>>> {
266 if let Self::[<$name Lease>](binding, _) = self {
267 Some(binding)
268 } else {
269 None
270 }
271 }
272
273 pub(super) fn [<as_ $name:snake _lease_mut>](&mut self) -> Option<(&Arc<Lease<$name>>, &mut bool)> {
274 if let Self::[<$name Lease>](binding, is_bound) = self {
275 Some((binding, is_bound))
276 } else {
277 None
278 }
279 }
280 }
281 }
282 }
283}
284
285bind_lease!(AccelerationStructure);
286bind_lease!(Image);
287bind_lease!(Buffer);
288
289pub trait Unbind<Graph, Binding> {
293 fn unbind(self, graph: &mut Graph) -> Binding;
297}