1use {
2 super::{
3 AccessType, Binding, Command, Graph, Node, Resource, Subresource, SubresourceRange,
4 ViewInfo,
5 },
6 crate::{
7 ExecutionPipeline,
8 driver::{compute::ComputePipeline, graphic::GraphicPipeline, ray_trace::RayTracePipeline},
9 },
10 std::marker::PhantomData,
11};
12
13pub trait Pipeline<'a> {
17 type Command;
19
20 fn bind_cmd(self, _: Command<'a>) -> Self::Command;
24}
25
26macro_rules! pipeline {
27 ($name:ident) => {
28 paste::paste! {
29 impl<'a> Pipeline<'a> for [<$name Pipeline>] {
30 type Command = PipelineCommand<'a, [<$name Pipeline>]>;
31
32 fn bind_cmd(self, mut cmd: Command<'a>) -> Self::Command {
33 {
34 let cmd = cmd.cmd_mut();
35 if cmd.expect_last_exec().pipeline.is_some() {
36 cmd.execs.push(Default::default());
37 }
38
39 cmd.expect_last_exec_mut().pipeline
40 = Some(ExecutionPipeline::$name(self));
41 }
42
43 Self::Command {
44 __: PhantomData,
45 cmd,
46 }
47 }
48 }
49
50 impl<'a> Pipeline<'a> for &'a [<$name Pipeline>] {
51 type Command = PipelineCommand<'a, [<$name Pipeline>]>;
52
53 fn bind_cmd(self, mut cmd: Command<'a>) -> Self::Command {
54 {
55 let cmd = cmd.cmd_mut();
56 if cmd.expect_last_exec().pipeline.is_some() {
57 cmd.execs.push(Default::default());
58 }
59
60 cmd.expect_last_exec_mut().pipeline
61 = Some(ExecutionPipeline::$name(self.clone()));
62 }
63
64 Self::Command {
65 __: PhantomData,
66 cmd,
67 }
68 }
69
70 }
71
72 impl ExecutionPipeline {
73 #[allow(unused)]
74 pub(crate) fn [<is_ $name:snake>](&self) -> bool {
75 matches!(self, Self::$name(_))
76 }
77
78 #[allow(unused)]
79 pub(crate) fn [<unwrap_ $name:snake>](&self) -> &[<$name Pipeline>] {
80 if let Self::$name(binding) = self {
81 &binding
82 } else {
83 panic!();
84 }
85 }
86 }
87 }
88 };
89}
90
91pipeline!(Compute);
93pipeline!(Graphic);
94pipeline!(RayTrace);
95
96pub struct PipelineCommand<'c, T> {
98 pub(super) __: PhantomData<T>,
99 pub(super) cmd: Command<'c>,
100}
101
102impl<'c, T> PipelineCommand<'c, T> {
104 pub fn bind_pipeline<P>(self, pipeline: P) -> P::Command
116 where
117 P: Pipeline<'c>,
118 {
119 pipeline.bind_cmd(self.cmd)
120 }
121
122 pub fn bind_resource<R>(&mut self, resource: R) -> R::Node
127 where
128 R: Resource,
129 {
130 self.cmd.bind_resource(resource)
131 }
132
133 pub fn end_cmd(self) -> &'c mut Graph {
135 self.cmd.end_cmd()
136 }
137
138 pub fn resource<N>(&self, resource_node: N) -> &N::Resource
141 where
142 N: Node,
143 {
144 self.cmd.resource(resource_node)
145 }
146
147 pub fn resource_access<N>(mut self, resource_node: N, access: AccessType) -> Self
153 where
154 N: Node + Subresource,
155 SubresourceRange: From<N::Range>,
156 {
157 self.cmd.set_resource_access(resource_node, access);
158 self
159 }
160
161 pub fn set_resource_access<N>(&mut self, resource_node: N, access: AccessType) -> &mut Self
167 where
168 N: Node + Subresource,
169 SubresourceRange: From<N::Range>,
170 {
171 self.cmd.set_resource_access(resource_node, access);
172 self
173 }
174
175 pub fn set_shader_resource_access<N>(
181 &mut self,
182 binding: impl Into<Binding>,
183 resource_node: N,
184 access: AccessType,
185 ) -> &mut Self
186 where
187 N: Node + Subresource,
188 N::Info: Copy,
189 SubresourceRange: From<N::Info>,
190 ViewInfo: From<N::Info>,
191 {
192 let subresource = resource_node.info(&self.cmd.graph.resources);
193
194 self.set_shader_subresource_access(binding, resource_node, subresource, access)
195 }
196
197 pub fn set_shader_subresource_access<N>(
204 &mut self,
205 binding: impl Into<Binding>,
206 resource_node: N,
207 subresource: impl Into<N::Info>,
208 access: AccessType,
209 ) -> &mut Self
210 where
211 N: Node + Subresource,
212 N::Info: Copy,
213 SubresourceRange: From<N::Info>,
214 ViewInfo: From<N::Info>,
215 {
216 let binding = binding.into();
217 let subresource = subresource.into();
218 let node_idx = resource_node.index();
219
220 self.cmd.push_subresource_access(
221 resource_node,
222 SubresourceRange::from(subresource),
223 access,
224 );
225
226 assert!(
227 self.cmd
228 .cmd_mut()
229 .expect_last_exec_mut()
230 .bindings
231 .insert(binding, (node_idx, subresource.into()))
232 .is_none(),
233 "binding {binding:?} has already been bound"
234 );
235
236 self
237 }
238
239 pub fn set_subresource_access<N>(
245 &mut self,
246 resource_node: N,
247 subresource: impl Into<N::Range>,
248 access: AccessType,
249 ) -> &mut Self
250 where
251 N: Node + Subresource,
252 SubresourceRange: From<N::Range>,
253 {
254 self.cmd
255 .set_subresource_access(resource_node, subresource, access);
256 self
257 }
258
259 pub fn shader_resource_access<N>(
265 mut self,
266 binding: impl Into<Binding>,
267 resource_node: N,
268 access: AccessType,
269 ) -> Self
270 where
271 N: Node + Subresource,
272 N::Info: Copy,
273 SubresourceRange: From<N::Info>,
274 ViewInfo: From<N::Info>,
275 {
276 self.set_shader_resource_access(binding, resource_node, access);
277 self
278 }
279
280 pub fn shader_subresource_access<N>(
287 mut self,
288 binding: impl Into<Binding>,
289 resource_node: N,
290 subresource: impl Into<N::Info>,
291 access: AccessType,
292 ) -> Self
293 where
294 N: Node + Subresource,
295 N::Info: Copy,
296 SubresourceRange: From<N::Info>,
297 ViewInfo: From<N::Info>,
298 {
299 self.set_shader_subresource_access(binding, resource_node, subresource, access);
300 self
301 }
302
303 pub fn subresource_access<N>(
309 mut self,
310 resource_node: N,
311 subresource: impl Into<N::Range>,
312 access: AccessType,
313 ) -> Self
314 where
315 N: Node + Subresource,
316 SubresourceRange: From<N::Range>,
317 {
318 self.cmd
319 .set_subresource_access(resource_node, subresource, access);
320 self
321 }
322}
323
324#[allow(deprecated)]
325#[allow(unused)]
326mod deprecated {
327 use {
328 crate::{
329 Graph, Node, Resource,
330 cmd::{Binding, PipelineCommand, Subresource, SubresourceRange, ViewInfo},
331 deprecated::Info,
332 graph::pass_ref::ViewType,
333 },
334 ash::vk,
335 vk_sync::AccessType,
336 };
337
338 impl<'a, T> PipelineCommand<'a, T> {
339 #[deprecated = "use shader_resource_access function"]
340 #[doc(hidden)]
341 pub fn access_descriptor<N>(
342 self,
343 descriptor: impl Into<Binding>,
344 node: N,
345 access: AccessType,
346 ) -> Self
347 where
348 N: Node + Info + Subresource,
349 ViewType: From<<N as Subresource>::Info>,
350 <N as Subresource>::Info: Copy + From<<N as Info>::Type>,
351 <N as Subresource>::Range: From<<N as Subresource>::Info>,
352 SubresourceRange: From<N::Range>,
353 {
354 let view_info = Subresource::info(&node, &self.cmd.graph.resources);
355
356 self.access_descriptor_as(descriptor, node, access, view_info)
357 }
358
359 #[deprecated = "use shader_subresource_access function"]
360 #[doc(hidden)]
361 pub fn access_descriptor_as<N>(
362 self,
363 descriptor: impl Into<Binding>,
364 node: N,
365 access: AccessType,
366 view_info: impl Into<N::Info>,
367 ) -> Self
368 where
369 N: Node + Subresource,
370 <N as Subresource>::Info: Copy + Into<ViewType>,
371 <N as Subresource>::Range: From<<N as Subresource>::Info>,
372 SubresourceRange: From<N::Range>,
373 {
374 let view_info = view_info.into();
375 let subresource = <N as Subresource>::Range::from(view_info);
376
377 self.access_descriptor_subrange(descriptor, node, access, view_info, subresource)
378 }
379
380 #[deprecated = "use shader_subresource_access function"]
381 #[doc(hidden)]
382 pub fn access_descriptor_subrange<N>(
383 mut self,
384 descriptor: impl Into<Binding>,
385 node: N,
386 access: AccessType,
387 view_info: impl Into<N::Info>,
388 subresource: impl Into<N::Range>,
389 ) -> Self
390 where
391 N: Node + Subresource,
392 <N as Subresource>::Info: Into<ViewType>,
393 SubresourceRange: From<N::Range>,
394 {
395 let descriptor = descriptor.into();
396 let view_info = view_info.into();
397 let node_idx = node.index();
398
399 self.cmd.push_subresource_access(
400 node,
401 SubresourceRange::from(subresource.into()),
402 access,
403 );
404
405 assert!(
406 self.cmd
407 .cmd_mut()
408 .expect_last_exec_mut()
409 .bindings
410 .insert(descriptor, (node_idx, view_info.into()))
411 .is_none(),
412 "descriptor {descriptor:?} has already been bound"
413 );
414
415 self
416 }
417
418 #[deprecated = "use resource_access function"]
419 #[doc(hidden)]
420 pub fn access_node<N>(mut self, node: N, access: AccessType) -> Self
421 where
422 N: Node + Subresource,
423 SubresourceRange: From<N::Range>,
424 {
425 self.resource_access(node, access)
426 }
427
428 #[deprecated = "use subresource_access function"]
429 #[doc(hidden)]
430 pub fn access_node_subrange<N>(
431 mut self,
432 node: N,
433 access: AccessType,
434 subresource: impl Into<N::Range>,
435 ) -> Self
436 where
437 N: Node + Subresource,
438 SubresourceRange: From<N::Range>,
439 {
440 self.access_node_subrange_mut(node, access, subresource);
441 self
442 }
443
444 #[deprecated = "use set_subresource_access function"]
445 #[doc(hidden)]
446 pub fn access_node_subrange_mut<N>(
447 &mut self,
448 node: N,
449 access: AccessType,
450 subresource: impl Into<N::Range>,
451 ) -> &mut Self
452 where
453 N: Node + Subresource,
454 SubresourceRange: From<N::Range>,
455 {
456 self.set_subresource_access(node, subresource, access)
457 }
458
459 #[deprecated = "use bind_resource function"]
460 #[doc(hidden)]
461 pub fn bind_node<R>(&mut self, resource: R) -> R::Node
462 where
463 R: Resource,
464 {
465 self.bind_resource(resource)
466 }
467
468 #[deprecated = "use device_address function of resource function result"]
469 #[doc(hidden)]
470 pub fn node_device_address(&self, node: impl Node) -> vk::DeviceAddress {
471 let idx = node.index();
472
473 self.cmd.graph.resources[idx]
474 .expect_buffer()
475 .device_address()
476 }
477
478 #[deprecated = "dereference info field of resource function result"]
479 #[doc(hidden)]
480 pub fn node_info<N>(&self, node: N) -> N::Type
481 where
482 N: Node + Info,
483 {
484 node.info(&self.cmd.graph.resources)
485 }
486
487 #[deprecated = "use end_cmd function"]
488 #[doc(hidden)]
489 pub fn submit_pass(self) -> &'a mut Graph {
490 self.end_cmd()
491 }
492 }
493}