screen_13/graph/
node.rs

1//! Bindings for Vulkan smart-pointer resources.
2
3use {
4    super::{Information, NodeIndex, RenderGraph, Unbind},
5    crate::{
6        driver::{
7            accel_struct::{AccelerationStructure, AccelerationStructureInfo},
8            buffer::{Buffer, BufferInfo},
9            image::{Image, ImageInfo},
10        },
11        pool::Lease,
12    },
13    std::sync::Arc,
14};
15
16/// Specifies either an owned acceleration structure or an acceleration structure leased from a
17/// pool.
18#[derive(Debug)]
19pub enum AnyAccelerationStructureNode {
20    /// An owned acceleration structure.
21    AccelerationStructure(AccelerationStructureNode),
22
23    /// An acceleration structure leased from a pool.
24    AccelerationStructureLease(AccelerationStructureLeaseNode),
25}
26
27impl Clone for AnyAccelerationStructureNode {
28    fn clone(&self) -> Self {
29        *self
30    }
31}
32
33impl Copy for AnyAccelerationStructureNode {}
34
35impl Information for AnyAccelerationStructureNode {
36    type Info = AccelerationStructureInfo;
37
38    fn get(self, graph: &RenderGraph) -> Self::Info {
39        match self {
40            Self::AccelerationStructure(node) => node.get(graph),
41            Self::AccelerationStructureLease(node) => node.get(graph),
42        }
43    }
44}
45
46impl From<AccelerationStructureNode> for AnyAccelerationStructureNode {
47    fn from(node: AccelerationStructureNode) -> Self {
48        Self::AccelerationStructure(node)
49    }
50}
51
52impl From<AccelerationStructureLeaseNode> for AnyAccelerationStructureNode {
53    fn from(node: AccelerationStructureLeaseNode) -> Self {
54        Self::AccelerationStructureLease(node)
55    }
56}
57
58impl Node for AnyAccelerationStructureNode {
59    fn index(self) -> NodeIndex {
60        match self {
61            Self::AccelerationStructure(node) => node.index(),
62            Self::AccelerationStructureLease(node) => node.index(),
63        }
64    }
65}
66
67/// Specifies either an owned buffer or a buffer leased from a pool.
68#[derive(Debug)]
69pub enum AnyBufferNode {
70    /// An owned buffer.
71    Buffer(BufferNode),
72
73    /// A buffer leased from a pool.
74    BufferLease(BufferLeaseNode),
75}
76
77impl Clone for AnyBufferNode {
78    fn clone(&self) -> Self {
79        *self
80    }
81}
82
83impl Copy for AnyBufferNode {}
84
85impl Information for AnyBufferNode {
86    type Info = BufferInfo;
87
88    fn get(self, graph: &RenderGraph) -> Self::Info {
89        match self {
90            Self::Buffer(node) => node.get(graph),
91            Self::BufferLease(node) => node.get(graph),
92        }
93    }
94}
95
96impl From<BufferNode> for AnyBufferNode {
97    fn from(node: BufferNode) -> Self {
98        Self::Buffer(node)
99    }
100}
101
102impl From<BufferLeaseNode> for AnyBufferNode {
103    fn from(node: BufferLeaseNode) -> Self {
104        Self::BufferLease(node)
105    }
106}
107
108impl Node for AnyBufferNode {
109    fn index(self) -> NodeIndex {
110        match self {
111            Self::Buffer(node) => node.index(),
112            Self::BufferLease(node) => node.index(),
113        }
114    }
115}
116
117/// Specifies either an owned image or an image leased from a pool.
118///
119/// The image may also be a special swapchain type of image.
120#[derive(Debug)]
121pub enum AnyImageNode {
122    /// An owned image.
123    Image(ImageNode),
124
125    /// An image leased from a pool.
126    ImageLease(ImageLeaseNode),
127
128    /// A special swapchain image.
129    SwapchainImage(SwapchainImageNode),
130}
131
132impl Clone for AnyImageNode {
133    fn clone(&self) -> Self {
134        *self
135    }
136}
137
138impl Copy for AnyImageNode {}
139
140impl Information for AnyImageNode {
141    type Info = ImageInfo;
142
143    fn get(self, graph: &RenderGraph) -> Self::Info {
144        match self {
145            Self::Image(node) => node.get(graph),
146            Self::ImageLease(node) => node.get(graph),
147            Self::SwapchainImage(node) => node.get(graph),
148        }
149    }
150}
151
152impl From<ImageNode> for AnyImageNode {
153    fn from(node: ImageNode) -> Self {
154        Self::Image(node)
155    }
156}
157
158impl From<ImageLeaseNode> for AnyImageNode {
159    fn from(node: ImageLeaseNode) -> Self {
160        Self::ImageLease(node)
161    }
162}
163
164impl From<SwapchainImageNode> for AnyImageNode {
165    fn from(node: SwapchainImageNode) -> Self {
166        Self::SwapchainImage(node)
167    }
168}
169
170impl Node for AnyImageNode {
171    fn index(self) -> NodeIndex {
172        match self {
173            Self::Image(node) => node.index(),
174            Self::ImageLease(node) => node.index(),
175            Self::SwapchainImage(node) => node.index(),
176        }
177    }
178}
179
180/// A Vulkan resource which has been bound to a [`RenderGraph`] using [`RenderGraph::bind_node`].
181pub trait Node: Copy {
182    /// The internal node index of this bound resource.
183    fn index(self) -> NodeIndex;
184}
185
186macro_rules! node {
187    ($name:ident) => {
188        paste::paste! {
189            /// Resource node.
190            #[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
191            pub struct [<$name Node>] {
192                pub(super) idx: NodeIndex,
193            }
194
195            impl [<$name Node>] {
196                pub(super) fn new(idx: NodeIndex) -> Self {
197                    Self {
198                        idx,
199                    }
200                }
201            }
202
203            impl Clone for [<$name Node>] {
204                fn clone(&self) -> Self {
205                    *self
206                }
207            }
208
209            impl Copy for [<$name Node>] {}
210
211            impl Node for [<$name Node>] {
212                fn index(self) -> NodeIndex {
213                    self.idx
214                }
215            }
216        }
217    };
218}
219
220node!(AccelerationStructure);
221node!(AccelerationStructureLease);
222node!(Buffer);
223node!(BufferLease);
224node!(Image);
225node!(ImageLease);
226node!(SwapchainImage);
227
228macro_rules! node_unbind {
229    ($name:ident) => {
230        paste::paste! {
231            impl Unbind<RenderGraph, Arc<$name>> for [<$name Node>] {
232                fn unbind(self, graph: &mut RenderGraph) -> Arc<$name> {
233                    let binding = &mut graph.bindings[self.idx];
234                    let res = Arc::clone(
235                        binding
236                            .[<as_ $name:snake>]()
237                            .unwrap()
238                    );
239                    binding.unbind();
240
241                    res
242                }
243            }
244        }
245    };
246}
247
248node_unbind!(AccelerationStructure);
249node_unbind!(Buffer);
250node_unbind!(Image);
251
252macro_rules! node_unbind_lease {
253    ($name:ident) => {
254        paste::paste! {
255            impl Unbind<RenderGraph, Arc<Lease<$name>>> for [<$name LeaseNode>] {
256                fn unbind(self, graph: &mut RenderGraph) -> Arc<Lease<$name>> {
257                    let binding = &mut graph.bindings[self.idx];
258                    let res = Arc::clone(
259                        binding
260                            .[<as_ $name:snake _lease>]()
261                            .unwrap()
262                    );
263                    binding.unbind();
264
265                    res
266                }
267            }
268        }
269    };
270}
271
272node_unbind_lease!(AccelerationStructure);
273node_unbind_lease!(Buffer);
274node_unbind_lease!(Image);