rendy_chain/chain/
link.rs1use crate::{
2 node::State,
3 resource::{AccessFlags, Resource},
4 schedule::{QueueId, SubmissionId},
5};
6
7#[derive(Clone, Copy, Debug)]
10pub struct LinkQueueState<R: Resource> {
11 pub first: usize,
12 pub last: usize,
13 pub access: R::Access,
14 pub stages: rendy_core::hal::pso::PipelineStage,
15}
16
17impl<R> LinkQueueState<R>
18where
19 R: Resource,
20{
21 fn new(node: &LinkNode<R>) -> Self {
22 LinkQueueState {
23 first: node.sid.index(),
24 last: node.sid.index(),
25 access: node.state.access,
26 stages: node.state.stages,
27 }
28 }
29
30 fn push(&mut self, node: &LinkNode<R>) {
31 assert!(self.last < node.sid.index());
32 self.access |= node.state.access;
33 self.stages |= node.state.stages;
34 self.last = node.sid.index();
35 }
36}
37
38#[derive(Clone, Debug)]
43pub struct Link<R: Resource> {
44 access: R::Access,
46
47 usage: R::Usage,
49
50 layout: R::Layout,
52
53 stages: rendy_core::hal::pso::PipelineStage,
55
56 queue_count: usize,
58
59 queues: Vec<Option<LinkQueueState<R>>>,
61
62 family: rendy_core::hal::queue::QueueFamilyId,
64}
65
66#[derive(Debug)]
68pub struct LinkNode<R: Resource> {
69 pub sid: SubmissionId,
71
72 pub state: State<R>,
74}
75
76impl<R> Link<R>
77where
78 R: Resource,
79{
80 pub fn new(node: LinkNode<R>) -> Self {
87 let mut link = Link {
88 access: node.state.access,
89 usage: node.state.usage,
90 layout: node.state.layout,
91 stages: node.state.stages,
92 queue_count: 1,
93 queues: Vec::new(),
94 family: node.sid.family(),
95 };
96 link.ensure_queue(node.sid.queue().index());
97 link.queues[node.sid.queue().index()] = Some(LinkQueueState::new(&node));
98 link
99 }
100
101 fn ensure_queue(&mut self, index: usize) {
102 if index >= self.queues.len() {
103 let reserve = index - self.queues.len() + 1;
104 self.queues.reserve(reserve);
105 while index >= self.queues.len() {
106 self.queues.push(None);
107 }
108 }
109 }
110
111 pub fn family(&self) -> rendy_core::hal::queue::QueueFamilyId {
114 self.family
115 }
116
117 pub fn submission_state(&self, sid: SubmissionId) -> State<R> {
119 assert_eq!(sid.family(), self.family);
120 let lqs = self.queues[sid.queue().index()].as_ref().unwrap();
121 State {
122 access: lqs.access,
123 layout: self.layout,
124 stages: lqs.stages,
125 usage: self.usage,
126 }
127 }
128
129 pub fn state(&self) -> State<R> {
131 State {
132 access: self.access,
133 layout: self.layout,
134 stages: self.stages,
135 usage: self.usage,
136 }
137 }
138
139 pub fn access(&self) -> R::Access {
141 self.access
142 }
143
144 pub fn layout(&self) -> R::Layout {
146 self.layout
147 }
148
149 pub fn usage(&self) -> R::Usage {
151 self.usage
152 }
153
154 pub fn single_queue(&self) -> bool {
161 self.queue_count == 1
162 }
163
164 pub fn compatible(&self, node: &LinkNode<R>) -> bool {
167 self.family == node.sid.family() && !(self.access | node.state.access).exclusive()
169 }
170
171 pub fn add_node(&mut self, node: LinkNode<R>) {
183 assert_eq!(self.family, node.sid.family());
184 self.ensure_queue(node.sid.queue().index());
185
186 self.access |= node.state.access;
187 self.usage |= node.state.usage;
188 self.stages |= node.state.stages;
189
190 match &mut self.queues[node.sid.queue().index()] {
191 &mut Some(ref mut queue) => {
192 queue.push(&node);
193 }
194 slot @ &mut None => {
195 self.queue_count += 1;
196 *slot = Some(LinkQueueState::new(&node));
197 }
198 }
199 }
200
201 pub fn queues(&self) -> impl Iterator<Item = (QueueId, &LinkQueueState<R>)> {
208 let family = self.family;
209 self.queues
210 .iter()
211 .enumerate()
212 .filter_map(move |(index, queue)| {
213 queue
214 .as_ref()
215 .map(move |queue| (QueueId::new(family, index), queue))
216 })
217 }
218
219 pub fn queue(&self, qid: QueueId) -> &LinkQueueState<R> {
221 assert_eq!(qid.family(), self.family);
222 self.queues[qid.index()].as_ref().unwrap()
223 }
224}