1use std::sync::Arc;
39
40use crate::{
41 Node,
42 driver::{
43 accel_struct::{AccelerationStructure, AccelerationStructureSyncInfo},
44 buffer::{Buffer, BufferSyncInfo},
45 image::{Image, ImageSyncInfo},
46 swapchain::SwapchainImage,
47 },
48 pool::Lease,
49 private,
50 stream::{AccelerationStructureArg, BufferArg, ImageArg},
51};
52
53#[cfg(feature = "checked")]
54use crate::GraphId;
55
56use super::{AnyResource, NodeIndex};
57
58#[derive(Clone, Copy, Debug)]
60pub enum AnyAccelerationStructureNode {
61 Arg(AccelerationStructureArg),
63
64 Owned(AccelerationStructureNode),
66
67 Pooled(AccelerationStructureLeaseNode),
69}
70
71impl From<AccelerationStructureNode> for AnyAccelerationStructureNode {
72 fn from(node: AccelerationStructureNode) -> Self {
73 Self::Owned(node)
74 }
75}
76
77impl From<AccelerationStructureArg> for AnyAccelerationStructureNode {
78 fn from(node: AccelerationStructureArg) -> Self {
79 Self::Arg(node)
80 }
81}
82
83impl From<AccelerationStructureLeaseNode> for AnyAccelerationStructureNode {
84 fn from(node: AccelerationStructureLeaseNode) -> Self {
85 Self::Pooled(node)
86 }
87}
88
89impl private::NodeSealed for AnyAccelerationStructureNode {
90 fn borrow(self, resources: &[AnyResource]) -> &<Self as Node>::Resource {
91 resources[self.index()].expect_accel_struct()
92 }
93
94 fn borrow_at(self, resources: &[AnyResource], index: usize) -> &<Self as Node>::Resource {
95 resources[index].expect_accel_struct()
96 }
97
98 #[cfg(feature = "checked")]
99 fn assert_owner(&self, graph_id: GraphId) {
100 match self {
101 Self::Arg(node) => node.assert_owner(graph_id),
102 Self::Owned(node) => node.assert_owner(graph_id),
103 Self::Pooled(node) => node.assert_owner(graph_id),
104 }
105 }
106}
107
108impl Node for AnyAccelerationStructureNode {
109 type Resource = AccelerationStructure;
110 type SyncInfo = AccelerationStructureSyncInfo;
111
112 fn index(&self) -> usize {
113 match self {
114 Self::Arg(node) => node.index(),
115 Self::Owned(node) => node.index(),
116 Self::Pooled(node) => node.index(),
117 }
118 }
119}
120
121#[derive(Clone, Copy, Debug)]
123pub enum AnyBufferNode {
124 Arg(BufferArg),
126
127 Owned(BufferNode),
129
130 Pooled(BufferLeaseNode),
132}
133
134impl From<BufferNode> for AnyBufferNode {
135 fn from(node: BufferNode) -> Self {
136 Self::Owned(node)
137 }
138}
139
140impl From<BufferArg> for AnyBufferNode {
141 fn from(node: BufferArg) -> Self {
142 Self::Arg(node)
143 }
144}
145
146impl From<BufferLeaseNode> for AnyBufferNode {
147 fn from(node: BufferLeaseNode) -> Self {
148 Self::Pooled(node)
149 }
150}
151
152impl private::NodeSealed for AnyBufferNode {
153 fn borrow(self, resources: &[AnyResource]) -> &<Self as Node>::Resource {
154 resources[self.index()].expect_buffer()
155 }
156
157 fn borrow_at(self, resources: &[AnyResource], index: usize) -> &<Self as Node>::Resource {
158 resources[index].expect_buffer()
159 }
160
161 #[cfg(feature = "checked")]
162 fn assert_owner(&self, graph_id: GraphId) {
163 match self {
164 Self::Arg(node) => node.assert_owner(graph_id),
165 Self::Owned(node) => node.assert_owner(graph_id),
166 Self::Pooled(node) => node.assert_owner(graph_id),
167 }
168 }
169}
170
171impl Node for AnyBufferNode {
172 type Resource = Buffer;
173 type SyncInfo = BufferSyncInfo;
174
175 fn index(&self) -> usize {
176 match self {
177 Self::Arg(node) => node.index(),
178 Self::Owned(node) => node.index(),
179 Self::Pooled(node) => node.index(),
180 }
181 }
182}
183
184#[derive(Clone, Copy, Debug)]
188pub enum AnyImageNode {
189 Arg(ImageArg),
191
192 Owned(ImageNode),
194
195 Pooled(ImageLeaseNode),
197
198 Swapchain(SwapchainImageNode),
200}
201
202impl From<ImageNode> for AnyImageNode {
203 fn from(node: ImageNode) -> Self {
204 Self::Owned(node)
205 }
206}
207
208impl From<ImageArg> for AnyImageNode {
209 fn from(node: ImageArg) -> Self {
210 Self::Arg(node)
211 }
212}
213
214impl From<ImageLeaseNode> for AnyImageNode {
215 fn from(node: ImageLeaseNode) -> Self {
216 Self::Pooled(node)
217 }
218}
219
220impl From<SwapchainImageNode> for AnyImageNode {
221 fn from(node: SwapchainImageNode) -> Self {
222 Self::Swapchain(node)
223 }
224}
225
226impl private::NodeSealed for AnyImageNode {
227 fn borrow(self, resources: &[AnyResource]) -> &<Self as Node>::Resource {
228 resources[self.index()].expect_image()
229 }
230
231 fn borrow_at(self, resources: &[AnyResource], index: usize) -> &<Self as Node>::Resource {
232 resources[index].expect_image()
233 }
234
235 #[cfg(feature = "checked")]
236 fn assert_owner(&self, graph_id: GraphId) {
237 match self {
238 Self::Arg(node) => node.assert_owner(graph_id),
239 Self::Owned(node) => node.assert_owner(graph_id),
240 Self::Pooled(node) => node.assert_owner(graph_id),
241 Self::Swapchain(node) => node.assert_owner(graph_id),
242 }
243 }
244}
245
246impl Node for AnyImageNode {
247 type Resource = Image;
248 type SyncInfo = ImageSyncInfo;
249
250 fn index(&self) -> usize {
251 match self {
252 Self::Arg(node) => node.index(),
253 Self::Owned(node) => node.index(),
254 Self::Pooled(node) => node.index(),
255 Self::Swapchain(node) => node.index(),
256 }
257 }
258}
259
260#[derive(Clone, Copy, Debug)]
262pub enum AnyNode {
263 AccelerationStructure(AnyAccelerationStructureNode),
265
266 Buffer(AnyBufferNode),
268
269 Image(AnyImageNode),
271}
272
273macro_rules! any_node_from {
274 ($node:ty => $variant:ident) => {
275 impl From<$node> for AnyNode {
276 fn from(node: $node) -> Self {
277 Self::$variant(node.into())
278 }
279 }
280 };
281}
282
283any_node_from!(AnyAccelerationStructureNode => AccelerationStructure);
284any_node_from!(AnyBufferNode => Buffer);
285any_node_from!(AnyImageNode => Image);
286
287any_node_from!(AccelerationStructureNode => AccelerationStructure);
288any_node_from!(AccelerationStructureLeaseNode => AccelerationStructure);
289any_node_from!(BufferNode => Buffer);
290any_node_from!(BufferLeaseNode => Buffer);
291any_node_from!(ImageNode => Image);
292any_node_from!(ImageLeaseNode => Image);
293any_node_from!(SwapchainImageNode => Image);
294
295macro_rules! node {
296 ($name:ident, $resource:ty, $sync_info:ty, $fn_name:ident) => {
297 paste::paste! {
298 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
308 pub struct [<$name Node>] {
309 index: NodeIndex,
310
311 #[cfg(feature = "checked")]
312 graph_id: GraphId,
313 }
314
315 impl [<$name Node>] {
316 pub(crate) fn new(
317 index: usize,
318 #[cfg(feature = "checked")] graph_id: GraphId,
319 ) -> Self {
320 Self {
321 index,
322
323 #[cfg(feature = "checked")]
324 graph_id,
325 }
326 }
327 }
328
329 impl private::NodeSealed for [<$name Node>] {
330 fn borrow(self, resources: &[AnyResource]) -> &<Self as Node>::Resource {
331 let AnyResource::$name(res) = &resources[self.index] else {
332 panic!("invalid resource node handle");
333 };
334
335 res
336 }
337
338 fn borrow_at(
339 self,
340 resources: &[AnyResource],
341 index: usize,
342 ) -> &<Self as Node>::Resource {
343 let AnyResource::$name(res) = &resources[index] else {
344 panic!("invalid resource node handle");
345 };
346
347 res
348 }
349
350 #[cfg(feature = "checked")]
351 fn assert_owner(&self, _graph_id: GraphId) {
352 #[cfg(feature = "checked")]
353 assert!(self.graph_id == _graph_id, "node belongs to a different graph");
354 }
355 }
356
357 impl Node for [<$name Node>] {
358 type Resource = $resource;
359 type SyncInfo = $sync_info;
360
361 fn index(&self) -> usize {
362 self.index
363 }
364 }
365 }
366 };
367}
368
369node!(
370 AccelerationStructure,
371 Arc<AccelerationStructure>,
372 AccelerationStructureSyncInfo,
373 as_accel_struct
374);
375node!(
376 AccelerationStructureLease,
377 Arc<Lease<AccelerationStructure>>,
378 AccelerationStructureSyncInfo,
379 as_accel_struct
380);
381node!(Buffer, Arc<Buffer>, BufferSyncInfo, as_buffer);
382node!(BufferLease, Arc<Lease<Buffer>>, BufferSyncInfo, as_buffer);
383node!(Image, Arc<Image>, ImageSyncInfo, as_image);
384node!(ImageLease, Arc<Lease<Image>>, ImageSyncInfo, as_image);
385node!(
386 SwapchainImage,
387 SwapchainImage,
388 ImageSyncInfo,
389 as_swapchain_image
390);