1mod cmd_ref;
21mod compute;
22mod graphics;
23mod pipeline;
24mod ray_tracing;
25
26pub use {
27 self::{
28 cmd_ref::{
29 BuildAccelerationStructureIndirectInfo, BuildAccelerationStructureInfo, CommandRef,
30 UpdateAccelerationStructureIndirectInfo, UpdateAccelerationStructureInfo,
31 },
32 compute::ComputeCommandRef,
33 graphics::{ClearColorValue, GraphicsCommandRef},
34 pipeline::{Pipeline, PipelineCommand},
35 ray_tracing::RayTracingCommandRef,
36 },
37 super::{LoadOp, StoreOp},
38};
39
40use {
41 super::{
42 AccelerationStructureLeaseNode, AccelerationStructureNode, AnyAccelerationStructureNode,
43 AnyBufferNode, AnyImageNode, AnyResource, BufferLeaseNode, BufferNode, CommandData,
44 CommandExecution, CommandFunction, Execution, Graph, ImageLeaseNode, ImageNode, Node,
45 Resource, SwapchainImageNode,
46 },
47 crate::{
48 NodeIndex,
49 driver::{
50 buffer::BufferSubresourceRange, format_texel_block_extent, format_texel_block_size,
51 image::ImageViewInfo, image_subresource_range_from_layers,
52 },
53 stream::{AccelerationStructureArg, BufferArg, ImageArg},
54 },
55 ash::vk,
56 std::{ops::Range, sync::Arc},
57 vk_sync::AccessType,
58};
59
60pub(crate) type AttachmentIndex = u32;
62
63pub(crate) type BindingIndex = u32;
65
66pub(crate) type BindingOffset = u32;
68
69pub(crate) type DescriptorSetIndex = u32;
71
72pub struct Command<'a> {
86 pub(super) cmd_idx: usize,
87 pub(super) exec_idx: usize,
88 pub(super) graph: &'a mut Graph,
89}
90
91pub struct CommandBuilder<'a> {
93 cmd: Command<'a>,
94}
95
96impl<'a> CommandBuilder<'a> {
97 pub fn new(graph: &'a mut Graph) -> Self {
99 Self {
100 cmd: graph.begin_cmd(),
101 }
102 }
103
104 pub fn build(self) -> Command<'a> {
106 self.cmd
107 }
108
109 pub fn push_cmd(self) -> &'a mut Graph {
111 self.cmd.end_cmd()
112 }
113
114 #[allow(deprecated)]
116 pub fn blit_image(
117 mut self,
118 src: impl Into<AnyImageNode>,
119 dst: impl Into<AnyImageNode>,
120 filter: vk::Filter,
121 regions: impl AsRef<[vk::ImageBlit]> + 'static + Send,
122 ) -> Self {
123 self.cmd = self.cmd.blit_image(src, dst, filter, regions);
124 self
125 }
126
127 #[allow(deprecated)]
129 pub fn clear_color_image(
130 mut self,
131 image: impl Into<AnyImageNode>,
132 color: impl Into<ClearColorValue>,
133 ) -> Self {
134 self.cmd = self.cmd.clear_color_image(image, color);
135 self
136 }
137
138 #[allow(deprecated)]
140 pub fn clear_depth_stencil_image(
141 mut self,
142 image: impl Into<AnyImageNode>,
143 depth: f32,
144 stencil: u32,
145 ) -> Self {
146 self.cmd = self.cmd.clear_depth_stencil_image(image, depth, stencil);
147 self
148 }
149
150 #[allow(deprecated)]
152 pub fn copy_buffer(
153 mut self,
154 src: impl Into<AnyBufferNode>,
155 dst: impl Into<AnyBufferNode>,
156 regions: impl AsRef<[vk::BufferCopy]> + 'static + Send,
157 ) -> Self {
158 self.cmd = self.cmd.copy_buffer(src, dst, regions);
159 self
160 }
161
162 #[allow(deprecated)]
164 pub fn copy_buffer_to_image(
165 mut self,
166 src: impl Into<AnyBufferNode>,
167 dst: impl Into<AnyImageNode>,
168 regions: impl AsRef<[vk::BufferImageCopy]> + 'static + Send,
169 ) -> Self {
170 self.cmd = self.cmd.copy_buffer_to_image(src, dst, regions);
171 self
172 }
173
174 #[allow(deprecated)]
176 pub fn copy_image(
177 mut self,
178 src: impl Into<AnyImageNode>,
179 dst: impl Into<AnyImageNode>,
180 regions: impl AsRef<[vk::ImageCopy]> + 'static + Send,
181 ) -> Self {
182 self.cmd = self.cmd.copy_image(src, dst, regions);
183 self
184 }
185
186 #[allow(deprecated)]
188 pub fn copy_image_to_buffer(
189 mut self,
190 src: impl Into<AnyImageNode>,
191 dst: impl Into<AnyBufferNode>,
192 regions: impl AsRef<[vk::BufferImageCopy]> + 'static + Send,
193 ) -> Self {
194 self.cmd = self.cmd.copy_image_to_buffer(src, dst, regions);
195 self
196 }
197
198 #[allow(deprecated)]
200 pub fn fill_buffer(
201 mut self,
202 buffer: impl Into<AnyBufferNode>,
203 region: Range<vk::DeviceSize>,
204 data: u32,
205 ) -> Self {
206 self.cmd = self.cmd.fill_buffer(buffer, region, data);
207 self
208 }
209
210 pub fn update_buffer(
212 mut self,
213 buffer: impl Into<AnyBufferNode>,
214 offset: vk::DeviceSize,
215 data: impl AsRef<[u8]> + 'static + Send,
216 ) -> Self {
217 self.cmd = self.cmd.update_buffer(buffer, offset, data);
218 self
219 }
220}
221
222#[allow(private_bounds)]
223impl<'a> Command<'a> {
224 pub(super) fn new(graph: &'a mut Graph) -> Self {
225 let cmd_idx = graph.cmds.len();
226 graph.cmds.push(CommandData {
227 execs: vec![Default::default()], #[cfg(debug_assertions)]
229 name: None,
230 stream_scope_id: None,
231 tracking: Default::default(),
232 });
233
234 Self {
235 cmd_idx,
236 exec_idx: 0,
237 graph,
238 }
239 }
240
241 pub fn builder(graph: &'a mut Graph) -> CommandBuilder<'a> {
243 CommandBuilder::new(graph)
244 }
245
246 pub fn into_builder(self) -> CommandBuilder<'a> {
248 CommandBuilder { cmd: self }
249 }
250
251 pub fn track_execution(&mut self) -> CommandExecution {
256 self.cmd_mut().tracking.track()
257 }
258
259 fn cmd(&self) -> &CommandData {
260 &self.graph.cmds[self.cmd_idx]
261 }
262
263 fn cmd_mut(&mut self) -> &mut CommandData {
264 &mut self.graph.cmds[self.cmd_idx]
265 }
266
267 pub fn bind_resource<R>(&mut self, resource: R) -> R::Node
272 where
273 R: Resource,
274 {
275 self.graph.bind_resource(resource)
276 }
277
278 pub fn bind_pipeline<P>(self, pipeline: P) -> P::Command
287 where
288 P: Pipeline<'a>,
289 {
290 pipeline.bind_cmd(self)
291 }
292
293 pub fn debug_name(mut self, name: impl Into<String>) -> Self {
295 self.set_debug_name(name);
296 self
297 }
298
299 pub fn end_cmd(self) -> &'a mut Graph {
302 if self.exec_idx == 0 {
304 self.graph.cmds.pop();
305 }
306
307 self.graph
308 }
309
310 fn push_exec(&mut self, func: impl FnOnce(CommandRef) + Send + 'static) {
311 let cmd = self.cmd_mut();
312 let exec = {
313 let last_exec = cmd.expect_last_exec_mut();
314 last_exec.func = Some(CommandFunction::Once(Box::new(func)));
315
316 Execution {
317 pipeline: last_exec.pipeline.clone(),
318 ..Default::default()
319 }
320 };
321
322 cmd.execs.push(exec);
323 self.exec_idx += 1;
324 }
325
326 pub(crate) fn push_reusable_exec(
327 &mut self,
328 func: impl for<'r> Fn(CommandRef<'r>) + Send + Sync + 'static,
329 ) {
330 let cmd = self.cmd_mut();
331 let exec = {
332 let last_exec = cmd.expect_last_exec_mut();
333 last_exec.func = Some(CommandFunction::Reusable(Arc::new(func)));
334
335 Execution {
336 pipeline: last_exec.pipeline.clone(),
337 ..Default::default()
338 }
339 };
340
341 cmd.execs.push(exec);
342 self.exec_idx += 1;
343 }
344
345 fn push_subresource_access(
346 &mut self,
347 resource_node: impl Node,
348 subresource: SubresourceRange,
349 access: AccessType,
350 ) {
351 self.graph.assert_node_owner(&resource_node);
352
353 let node_idx = resource_node.index();
354
355 self.push_subresource_access_index(node_idx, subresource, access);
356 }
357
358 pub(crate) fn push_subresource_access_index(
359 &mut self,
360 node_idx: NodeIndex,
361 subresource: SubresourceRange,
362 access: AccessType,
363 ) {
364 debug_assert!(self.graph.resources.get(node_idx).is_some());
365
366 self.cmd_mut().expect_last_exec_mut().accesses.push(
367 node_idx,
368 SubresourceAccess {
369 access,
370 subresource,
371 },
372 );
373 }
374
375 pub fn record_cmd(mut self, func: impl FnOnce(CommandRef<'_>) + Send + 'static) -> Self {
383 self.record_cmd_mut(func);
384 self
385 }
386
387 pub fn record_cmd_mut(&mut self, func: impl FnOnce(CommandRef<'_>) + Send + 'static) {
389 self.push_exec(move |cmd| {
390 func(cmd);
391 });
392 }
393
394 pub fn blit_image(
396 mut self,
397 src: impl Into<AnyImageNode>,
398 dst: impl Into<AnyImageNode>,
399 filter: vk::Filter,
400 regions: impl AsRef<[vk::ImageBlit]> + 'static + Send,
401 ) -> Self {
402 let src = src.into();
403 let dst = dst.into();
404 let regions = Arc::<[vk::ImageBlit]>::from(regions.as_ref());
405
406 for region in regions.as_ref() {
407 self.set_subresource_access(
408 src,
409 image_subresource_range_from_layers(region.src_subresource),
410 AccessType::TransferRead,
411 );
412 self.set_subresource_access(
413 dst,
414 image_subresource_range_from_layers(region.dst_subresource),
415 AccessType::TransferWrite,
416 );
417 }
418
419 self.record_stream_mut(move |cmd| {
420 let src_image = cmd.resource(src).handle;
421 let dst_image = cmd.resource(dst).handle;
422
423 unsafe {
424 cmd.device.cmd_blit_image(
425 cmd.handle,
426 src_image,
427 vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
428 dst_image,
429 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
430 regions.as_ref(),
431 filter,
432 );
433 }
434 });
435 self
436 }
437
438 pub fn clear_color_image(
440 mut self,
441 image: impl Into<AnyImageNode>,
442 color: impl Into<ClearColorValue>,
443 ) -> Self {
444 let color = color.into().into();
445 let image = image.into();
446 let image_view = self.graph.resources[image.index()]
447 .expect_image_info()
448 .into();
449
450 self.set_subresource_access(image, image_view, AccessType::TransferWrite);
451 self.record_stream_mut(move |cmd| {
452 let image = cmd.resource(image);
453
454 unsafe {
455 cmd.device.cmd_clear_color_image(
456 cmd.handle,
457 image.handle,
458 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
459 &color,
460 &[image_view],
461 );
462 }
463 });
464 self
465 }
466
467 pub fn clear_depth_stencil_image(
469 mut self,
470 image: impl Into<AnyImageNode>,
471 depth: f32,
472 stencil: u32,
473 ) -> Self {
474 let image = image.into();
475 let image_view = self.graph.resources[image.index()]
476 .expect_image_info()
477 .into();
478
479 self.set_subresource_access(image, image_view, AccessType::TransferWrite);
480 self.record_stream_mut(move |cmd| {
481 let image = cmd.resource(image);
482
483 unsafe {
484 cmd.device.cmd_clear_depth_stencil_image(
485 cmd.handle,
486 image.handle,
487 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
488 &vk::ClearDepthStencilValue { depth, stencil },
489 &[image_view],
490 );
491 }
492 });
493 self
494 }
495
496 pub fn copy_buffer(
498 mut self,
499 src: impl Into<AnyBufferNode>,
500 dst: impl Into<AnyBufferNode>,
501 regions: impl AsRef<[vk::BufferCopy]> + 'static + Send,
502 ) -> Self {
503 let src = src.into();
504 let dst = dst.into();
505 let regions = Arc::<[vk::BufferCopy]>::from(regions.as_ref());
506
507 #[cfg(feature = "checked")]
508 let src_size = self.graph.resources[src.index()].expect_buffer_info().size;
509
510 #[cfg(feature = "checked")]
511 let dst_size = self.graph.resources[dst.index()].expect_buffer_info().size;
512
513 for region in regions.iter() {
514 #[cfg(feature = "checked")]
515 {
516 assert!(
517 region.src_offset + region.size <= src_size,
518 "source range end ({}) exceeds source size ({src_size})",
519 region.src_offset + region.size
520 );
521 assert!(
522 region.dst_offset + region.size <= dst_size,
523 "destination range end ({}) exceeds destination size ({dst_size})",
524 region.dst_offset + region.size
525 );
526 };
527
528 self.set_subresource_access(
529 src,
530 region.src_offset..region.src_offset + region.size,
531 AccessType::TransferRead,
532 );
533 self.set_subresource_access(
534 dst,
535 region.dst_offset..region.dst_offset + region.size,
536 AccessType::TransferWrite,
537 );
538 }
539
540 self.record_stream_mut(move |cmd| {
541 let src = cmd.resource(src);
542 let dst = cmd.resource(dst);
543
544 unsafe {
545 cmd.device
546 .cmd_copy_buffer(cmd.handle, src.handle, dst.handle, ®ions);
547 }
548 });
549 self
550 }
551
552 pub fn copy_buffer_to_image(
554 mut self,
555 src: impl Into<AnyBufferNode>,
556 dst: impl Into<AnyImageNode>,
557 regions: impl AsRef<[vk::BufferImageCopy]> + 'static + Send,
558 ) -> Self {
559 let src = src.into();
560 let dst = dst.into();
561 let dst_info = self.graph.resources[dst.index()].expect_image_info();
562 let regions = Arc::<[vk::BufferImageCopy]>::from(regions.as_ref());
563
564 for region in regions.iter() {
565 let block_bytes_size = format_texel_block_size(dst_info.format);
566 let (block_height, block_width) = format_texel_block_extent(dst_info.format);
567 let data_size = block_bytes_size
568 * (region.buffer_row_length / block_width)
569 * (region.buffer_image_height / block_height);
570
571 self.set_subresource_access(
572 src,
573 region.buffer_offset..region.buffer_offset + data_size as vk::DeviceSize,
574 AccessType::TransferRead,
575 );
576 self.set_subresource_access(
577 dst,
578 image_subresource_range_from_layers(region.image_subresource),
579 AccessType::TransferWrite,
580 );
581 }
582
583 self.record_stream_mut(move |cmd| {
584 let src = cmd.resource(src);
585 let dst = cmd.resource(dst);
586
587 unsafe {
588 cmd.device.cmd_copy_buffer_to_image(
589 cmd.handle,
590 src.handle,
591 dst.handle,
592 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
593 ®ions,
594 );
595 }
596 });
597 self
598 }
599
600 pub fn copy_image(
602 mut self,
603 src: impl Into<AnyImageNode>,
604 dst: impl Into<AnyImageNode>,
605 regions: impl AsRef<[vk::ImageCopy]> + 'static + Send,
606 ) -> Self {
607 let src = src.into();
608 let dst = dst.into();
609 let regions = Arc::<[vk::ImageCopy]>::from(regions.as_ref());
610
611 for region in regions.iter() {
612 self.set_subresource_access(
613 src,
614 image_subresource_range_from_layers(region.src_subresource),
615 AccessType::TransferRead,
616 );
617 self.set_subresource_access(
618 dst,
619 image_subresource_range_from_layers(region.dst_subresource),
620 AccessType::TransferWrite,
621 );
622 }
623
624 self.record_stream_mut(move |cmd| {
625 let src = cmd.resource(src);
626 let dst = cmd.resource(dst);
627
628 unsafe {
629 cmd.device.cmd_copy_image(
630 cmd.handle,
631 src.handle,
632 vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
633 dst.handle,
634 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
635 ®ions,
636 );
637 }
638 });
639 self
640 }
641
642 pub fn copy_image_to_buffer(
644 mut self,
645 src: impl Into<AnyImageNode>,
646 dst: impl Into<AnyBufferNode>,
647 regions: impl AsRef<[vk::BufferImageCopy]> + 'static + Send,
648 ) -> Self {
649 let src = src.into();
650 let src_info = self.graph.resources[src.index()].expect_image_info();
651 let dst = dst.into();
652 let regions = Arc::<[vk::BufferImageCopy]>::from(regions.as_ref());
653
654 for region in regions.iter() {
655 let block_bytes_size = format_texel_block_size(src_info.format);
656 let (block_height, block_width) = format_texel_block_extent(src_info.format);
657 let data_size = block_bytes_size
658 * (region.buffer_row_length / block_width)
659 * (region.buffer_image_height / block_height);
660
661 self.set_subresource_access(
662 src,
663 image_subresource_range_from_layers(region.image_subresource),
664 AccessType::TransferRead,
665 );
666 self.set_subresource_access(
667 dst,
668 region.buffer_offset..region.buffer_offset + data_size as vk::DeviceSize,
669 AccessType::TransferWrite,
670 );
671 }
672
673 self.record_stream_mut(move |cmd| {
674 let src = cmd.resource(src);
675 let dst = cmd.resource(dst);
676
677 unsafe {
678 cmd.device.cmd_copy_image_to_buffer(
679 cmd.handle,
680 src.handle,
681 vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
682 dst.handle,
683 ®ions,
684 );
685 }
686 });
687 self
688 }
689
690 pub fn fill_buffer(
692 mut self,
693 buffer: impl Into<AnyBufferNode>,
694 region: Range<vk::DeviceSize>,
695 data: u32,
696 ) -> Self {
697 let buffer = buffer.into();
698
699 self.set_subresource_access(buffer, region.clone(), AccessType::TransferWrite);
700 self.record_stream_mut(move |cmd| {
701 let buffer = cmd.resource(buffer);
702
703 unsafe {
704 cmd.device.cmd_fill_buffer(
705 cmd.handle,
706 buffer.handle,
707 region.start,
708 region.end - region.start,
709 data,
710 );
711 }
712 });
713 self
714 }
715
716 pub(crate) fn record_stream(
717 mut self,
718 func: impl for<'r> Fn(CommandRef<'r>) + Send + Sync + 'static,
719 ) -> Self {
720 self.record_stream_mut(func);
721 self
722 }
723
724 pub(crate) fn record_stream_mut(
725 &mut self,
726 func: impl for<'r> Fn(CommandRef<'r>) + Send + Sync + 'static,
727 ) {
728 self.push_reusable_exec(func);
729 }
730
731 pub fn resource<N>(&self, resource_node: N) -> &N::Resource
734 where
735 N: Node,
736 {
737 self.graph.resource(resource_node)
738 }
739
740 pub fn resource_access<N>(mut self, resource_node: N, access: AccessType) -> Self
746 where
747 N: Node + Subresource,
748 SubresourceRange: From<N::Range>,
749 {
750 self.set_resource_access(resource_node, access);
751 self
752 }
753
754 pub fn set_debug_name(&mut self, name: impl Into<String>) -> &mut Self {
756 #[cfg(debug_assertions)]
757 {
758 self.cmd_mut().name = Some(name.into());
759 }
760
761 #[cfg(not(debug_assertions))]
762 {
763 let _ = name;
764 }
765
766 self
767 }
768
769 pub fn set_resource_access<N>(&mut self, resource_node: N, access: AccessType)
771 where
772 N: Node + Subresource,
773 SubresourceRange: From<N::Range>,
774 {
775 let whole_resource = resource_node.range(&self.graph.resources);
776 let subresource = SubresourceRange::from(whole_resource);
777
778 self.push_subresource_access(resource_node, subresource, access);
779 }
780
781 pub(crate) fn set_stream_scope_id(&mut self, stream_scope_id: u64) {
782 self.cmd_mut().stream_scope_id = Some(stream_scope_id);
783 }
784
785 pub fn set_subresource_access<N>(
787 &mut self,
788 resource_node: N,
789 subresource: impl Into<N::Range>,
790 access: AccessType,
791 ) where
792 N: Node + Subresource,
793 SubresourceRange: From<N::Range>,
794 {
795 let subresource = subresource.into();
796 let subresource = SubresourceRange::from(subresource);
797
798 self.push_subresource_access(resource_node, subresource, access);
799 }
800
801 pub fn subresource_access<N>(
807 mut self,
808 resource_node: N,
809 subresource: impl Into<N::Range>,
810 access: AccessType,
811 ) -> Self
812 where
813 N: Node + Subresource,
814 SubresourceRange: From<N::Range>,
815 {
816 self.set_subresource_access(resource_node, subresource, access);
817 self
818 }
819
820 #[profiling::function]
829 pub fn update_buffer(
830 mut self,
831 buffer: impl Into<AnyBufferNode>,
832 offset: vk::DeviceSize,
833 data: impl AsRef<[u8]> + 'static + Send,
834 ) -> Self {
835 debug_assert!(data.as_ref().len() <= 64 * 1024);
836
837 let buffer = buffer.into();
838 let data_end = offset + data.as_ref().len() as vk::DeviceSize;
839
840 #[cfg(feature = "checked")]
841 {
842 assert!(
843 data.as_ref().len() <= 64 * 1024,
844 "data length ({}) exceeds vkCmdUpdateBuffer limit (65536)",
845 data.as_ref().len()
846 );
847
848 let buffer_info = self.graph.resources[buffer.index()].expect_buffer_info();
849
850 assert!(
851 data_end <= buffer_info.size,
852 "data range end ({data_end}) exceeds buffer size ({})",
853 buffer_info.size
854 );
855 }
856
857 let data = Arc::<[u8]>::from(data.as_ref());
858
859 self.set_subresource_access(buffer, offset..data_end, AccessType::TransferWrite);
860 self.record_stream_mut(move |cmd| {
861 let buffer = cmd.resource(buffer);
862
863 unsafe {
864 cmd.device
865 .cmd_update_buffer(cmd.handle, buffer.handle, offset, &data);
866 }
867 });
868 self
869 }
870}
871
872#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
890pub struct Binding {
891 pub binding: u32,
893
894 pub offset: u32,
896
897 pub set: u32,
899}
900
901impl Binding {
902 pub(super) fn into_tuple(self) -> (DescriptorSetIndex, BindingIndex, BindingOffset) {
903 (self.set, self.binding, self.offset)
904 }
905
906 pub(super) fn set(self) -> DescriptorSetIndex {
907 let (res, _, _) = self.into_tuple();
908 res
909 }
910}
911
912impl From<BindingIndex> for Binding {
913 fn from(binding: BindingIndex) -> Self {
914 Self {
915 binding,
916 offset: 0,
917 set: 0,
918 }
919 }
920}
921
922impl From<(DescriptorSetIndex, BindingIndex)> for Binding {
923 fn from((set, binding): (DescriptorSetIndex, BindingIndex)) -> Self {
924 Self {
925 binding,
926 offset: 0,
927 set,
928 }
929 }
930}
931
932impl From<(BindingIndex, [BindingOffset; 1])> for Binding {
933 fn from((binding, [offset]): (BindingIndex, [BindingOffset; 1])) -> Self {
934 Self {
935 binding,
936 offset,
937 set: 0,
938 }
939 }
940}
941
942impl From<(DescriptorSetIndex, BindingIndex, [BindingOffset; 1])> for Binding {
943 fn from(
944 (set, binding, [offset]): (DescriptorSetIndex, BindingIndex, [BindingOffset; 1]),
945 ) -> Self {
946 Self {
947 binding,
948 offset,
949 set,
950 }
951 }
952}
953
954#[allow(private_bounds)]
956pub trait Subresource: private::SubresourceSealed {
957 type Info;
959
960 type Range;
962}
963
964macro_rules! view_accel_struct {
965 ($name:ty) => {
966 impl Subresource for $name {
967 type Info = Self::Range;
968 type Range = ();
969 }
970
971 impl private::SubresourceSealed for $name {
972 fn info(&self, _: &[AnyResource]) -> <Self as Subresource>::Info
973 where
974 Self: Node + Subresource,
975 {
976 }
977
978 fn range(&self, resources: &[AnyResource]) -> <Self as Subresource>::Range
979 where
980 Self: Node + Subresource,
981 {
982 resources[self.index()].expect_accel_struct_info();
983 }
984 }
985 };
986}
987
988view_accel_struct!(AnyAccelerationStructureNode);
989view_accel_struct!(AccelerationStructureArg);
990view_accel_struct!(AccelerationStructureLeaseNode);
991view_accel_struct!(AccelerationStructureNode);
992
993macro_rules! view_buffer {
994 ($name:ty) => {
995 impl Subresource for $name {
996 type Info = Self::Range;
997 type Range = BufferSubresourceRange;
998 }
999
1000 impl private::SubresourceSealed for $name {
1001 fn info(&self, resources: &[AnyResource]) -> <Self as Subresource>::Info
1002 where
1003 Self: Node + Subresource,
1004 {
1005 self.range(resources)
1006 }
1007
1008 fn range(&self, resources: &[AnyResource]) -> <Self as Subresource>::Range
1009 where
1010 Self: Node + Subresource,
1011 {
1012 let idx = self.index();
1013
1014 resources[idx].expect_buffer_info().into()
1015 }
1016 }
1017 };
1018}
1019
1020view_buffer!(AnyBufferNode);
1021view_buffer!(BufferArg);
1022view_buffer!(BufferLeaseNode);
1023view_buffer!(BufferNode);
1024
1025macro_rules! view_image {
1026 ($name:ty) => {
1027 impl Subresource for $name {
1028 type Info = ImageViewInfo;
1029 type Range = vk::ImageSubresourceRange;
1030 }
1031
1032 impl private::SubresourceSealed for $name {
1033 fn info(&self, resources: &[AnyResource]) -> <Self as Subresource>::Info
1034 where
1035 Self: Node + Subresource,
1036 {
1037 let idx = self.index();
1038
1039 resources[idx].expect_image_info().into()
1040 }
1041
1042 fn range(&self, resources: &[AnyResource]) -> <Self as Subresource>::Range
1043 where
1044 Self: Node + Subresource,
1045 {
1046 self.info(resources).into()
1047 }
1048 }
1049 };
1050}
1051
1052view_image!(AnyImageNode);
1053view_image!(ImageArg);
1054view_image!(ImageLeaseNode);
1055view_image!(ImageNode);
1056view_image!(SwapchainImageNode);
1057
1058#[derive(Clone, Copy, Debug)]
1059pub(crate) enum SubresourceRange {
1060 AccelerationStructure,
1062
1063 Image(vk::ImageSubresourceRange),
1065
1066 Buffer(BufferSubresourceRange),
1068}
1069
1070impl SubresourceRange {
1071 pub(super) fn as_image(&self) -> Option<&vk::ImageSubresourceRange> {
1072 if let Self::Image(subresource) = self {
1073 Some(subresource)
1074 } else {
1075 None
1076 }
1077 }
1078
1079 pub(super) fn expect_image(&self) -> &vk::ImageSubresourceRange {
1080 self.as_image().expect("missing image subresource")
1081 }
1082}
1083
1084impl From<BufferSubresourceRange> for SubresourceRange {
1085 fn from(subresource: BufferSubresourceRange) -> Self {
1086 Self::Buffer(subresource)
1087 }
1088}
1089
1090impl From<()> for SubresourceRange {
1091 fn from(_: ()) -> Self {
1092 Self::AccelerationStructure
1093 }
1094}
1095
1096impl From<ImageViewInfo> for SubresourceRange {
1097 fn from(subresource: ImageViewInfo) -> Self {
1098 Self::Image(subresource.into())
1099 }
1100}
1101
1102impl From<vk::ImageSubresourceRange> for SubresourceRange {
1103 fn from(subresource: vk::ImageSubresourceRange) -> Self {
1104 Self::Image(subresource)
1105 }
1106}
1107
1108#[derive(Clone, Copy, Debug)]
1109pub(super) struct SubresourceAccess {
1110 pub access: AccessType,
1111 pub subresource: SubresourceRange,
1112}
1113
1114#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1116pub(crate) enum ViewInfo {
1117 AccelerationStructure,
1119
1120 Image(ImageViewInfo),
1122
1123 Buffer(BufferSubresourceRange),
1125}
1126
1127impl ViewInfo {
1128 pub(crate) fn as_buffer(&self) -> Option<&BufferSubresourceRange> {
1129 match self {
1130 Self::Buffer(info) => Some(info),
1131 _ => None,
1132 }
1133 }
1134
1135 pub(crate) fn as_image(&self) -> Option<&ImageViewInfo> {
1136 match self {
1137 Self::Image(info) => Some(info),
1138 _ => None,
1139 }
1140 }
1141
1142 pub(crate) fn expect_buffer(&self) -> &BufferSubresourceRange {
1143 self.as_buffer().expect("missing buffer view info")
1144 }
1145
1146 pub(crate) fn expect_image(&self) -> &ImageViewInfo {
1147 self.as_image().expect("missing image view info")
1148 }
1149}
1150
1151impl From<()> for ViewInfo {
1152 fn from(_: ()) -> Self {
1153 Self::AccelerationStructure
1154 }
1155}
1156
1157impl From<BufferSubresourceRange> for ViewInfo {
1158 fn from(info: BufferSubresourceRange) -> Self {
1159 Self::Buffer(info)
1160 }
1161}
1162
1163impl From<ImageViewInfo> for ViewInfo {
1164 fn from(info: ImageViewInfo) -> Self {
1165 Self::Image(info)
1166 }
1167}
1168
1169impl From<Range<vk::DeviceSize>> for ViewInfo {
1170 fn from(range: Range<vk::DeviceSize>) -> Self {
1171 Self::Buffer(BufferSubresourceRange {
1172 start: range.start,
1173 end: range.end,
1174 })
1175 }
1176}
1177
1178mod private {
1179 use crate::{AnyResource, Node};
1180
1181 pub(crate) trait SubresourceSealed: Sized {
1182 fn info(&self, resources: &[AnyResource]) -> <Self as super::Subresource>::Info
1183 where
1184 Self: Node + super::Subresource;
1185
1186 fn range(&self, resources: &[AnyResource]) -> <Self as super::Subresource>::Range
1187 where
1188 Self: Node + super::Subresource;
1189 }
1190}