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, TimestampQuery, TimestampQueryPlacement,
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 pub fn write_timestamp(&mut self) -> TimestampQuery {
266 let (exec_idx, placement) = if self.exec_idx == 0 {
267 (0, TimestampQueryPlacement::BeforeExec)
268 } else {
269 (self.exec_idx - 1, TimestampQueryPlacement::AfterExec)
270 };
271
272 self.graph
273 .write_timestamp_at(self.cmd_idx, exec_idx, placement)
274 }
275
276 fn cmd(&self) -> &CommandData {
277 &self.graph.cmds[self.cmd_idx]
278 }
279
280 fn cmd_mut(&mut self) -> &mut CommandData {
281 &mut self.graph.cmds[self.cmd_idx]
282 }
283
284 pub fn bind_resource<R>(&mut self, resource: R) -> R::Node
289 where
290 R: Resource,
291 {
292 self.graph.bind_resource(resource)
293 }
294
295 pub fn bind_pipeline<P>(self, pipeline: P) -> P::Command
304 where
305 P: Pipeline<'a>,
306 {
307 pipeline.bind_cmd(self)
308 }
309
310 pub fn debug_name(mut self, name: impl Into<String>) -> Self {
312 self.set_debug_name(name);
313 self
314 }
315
316 pub fn end_cmd(self) -> &'a mut Graph {
319 if self.exec_idx == 0 {
321 self.graph.cmds.pop();
322 }
323
324 self.graph
325 }
326
327 fn push_exec(&mut self, func: impl FnOnce(CommandRef) + Send + 'static) {
328 let cmd = self.cmd_mut();
329 let exec = {
330 let last_exec = cmd.expect_last_exec_mut();
331 last_exec.func = Some(CommandFunction::Once(Box::new(func)));
332
333 Execution {
334 pipeline: last_exec.pipeline.clone(),
335 ..Default::default()
336 }
337 };
338
339 cmd.execs.push(exec);
340 self.exec_idx += 1;
341 }
342
343 pub(crate) fn push_reusable_exec(
344 &mut self,
345 func: impl for<'r> Fn(CommandRef<'r>) + Send + Sync + 'static,
346 ) {
347 let cmd = self.cmd_mut();
348 let exec = {
349 let last_exec = cmd.expect_last_exec_mut();
350 last_exec.func = Some(CommandFunction::Reusable(Arc::new(func)));
351
352 Execution {
353 pipeline: last_exec.pipeline.clone(),
354 ..Default::default()
355 }
356 };
357
358 cmd.execs.push(exec);
359 self.exec_idx += 1;
360 }
361
362 fn push_subresource_access(
363 &mut self,
364 resource_node: impl Node,
365 subresource: SubresourceRange,
366 access: AccessType,
367 ) {
368 self.graph.assert_node_owner(&resource_node);
369
370 let node_idx = resource_node.index();
371
372 self.push_subresource_access_index(node_idx, subresource, access);
373 }
374
375 pub(crate) fn push_subresource_access_index(
376 &mut self,
377 node_idx: NodeIndex,
378 subresource: SubresourceRange,
379 access: AccessType,
380 ) {
381 debug_assert!(self.graph.resources.get(node_idx).is_some());
382
383 self.cmd_mut().expect_last_exec_mut().accesses.push(
384 node_idx,
385 SubresourceAccess {
386 access,
387 subresource,
388 },
389 );
390 }
391
392 pub fn record_cmd(mut self, func: impl FnOnce(CommandRef<'_>) + Send + 'static) -> Self {
400 self.record_cmd_mut(func);
401 self
402 }
403
404 pub fn record_cmd_mut(&mut self, func: impl FnOnce(CommandRef<'_>) + Send + 'static) {
406 self.push_exec(move |cmd| {
407 func(cmd);
408 });
409 }
410
411 pub fn blit_image(
413 mut self,
414 src: impl Into<AnyImageNode>,
415 dst: impl Into<AnyImageNode>,
416 filter: vk::Filter,
417 regions: impl AsRef<[vk::ImageBlit]> + 'static + Send,
418 ) -> Self {
419 let src = src.into();
420 let dst = dst.into();
421 let regions = Arc::<[vk::ImageBlit]>::from(regions.as_ref());
422
423 for region in regions.as_ref() {
424 self.set_subresource_access(
425 src,
426 image_subresource_range_from_layers(region.src_subresource),
427 AccessType::TransferRead,
428 );
429 self.set_subresource_access(
430 dst,
431 image_subresource_range_from_layers(region.dst_subresource),
432 AccessType::TransferWrite,
433 );
434 }
435
436 self.record_stream_mut(move |cmd| {
437 let src_image = cmd.resource(src).handle;
438 let dst_image = cmd.resource(dst).handle;
439
440 unsafe {
441 cmd.device.cmd_blit_image(
442 cmd.handle,
443 src_image,
444 vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
445 dst_image,
446 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
447 regions.as_ref(),
448 filter,
449 );
450 }
451 });
452 self
453 }
454
455 pub fn clear_color_image(
457 mut self,
458 image: impl Into<AnyImageNode>,
459 color: impl Into<ClearColorValue>,
460 ) -> Self {
461 let color = color.into().into();
462 let image = image.into();
463 let image_view = self.graph.resources[image.index()]
464 .expect_image_info()
465 .into();
466
467 self.set_subresource_access(image, image_view, AccessType::TransferWrite);
468 self.record_stream_mut(move |cmd| {
469 let image = cmd.resource(image);
470
471 unsafe {
472 cmd.device.cmd_clear_color_image(
473 cmd.handle,
474 image.handle,
475 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
476 &color,
477 &[image_view],
478 );
479 }
480 });
481 self
482 }
483
484 pub fn clear_depth_stencil_image(
486 mut self,
487 image: impl Into<AnyImageNode>,
488 depth: f32,
489 stencil: u32,
490 ) -> Self {
491 let image = image.into();
492 let image_view = self.graph.resources[image.index()]
493 .expect_image_info()
494 .into();
495
496 self.set_subresource_access(image, image_view, AccessType::TransferWrite);
497 self.record_stream_mut(move |cmd| {
498 let image = cmd.resource(image);
499
500 unsafe {
501 cmd.device.cmd_clear_depth_stencil_image(
502 cmd.handle,
503 image.handle,
504 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
505 &vk::ClearDepthStencilValue { depth, stencil },
506 &[image_view],
507 );
508 }
509 });
510 self
511 }
512
513 pub fn copy_buffer(
515 mut self,
516 src: impl Into<AnyBufferNode>,
517 dst: impl Into<AnyBufferNode>,
518 regions: impl AsRef<[vk::BufferCopy]> + 'static + Send,
519 ) -> Self {
520 let src = src.into();
521 let dst = dst.into();
522 let regions = Arc::<[vk::BufferCopy]>::from(regions.as_ref());
523
524 #[cfg(feature = "checked")]
525 let src_size = self.graph.resources[src.index()].expect_buffer_info().size;
526
527 #[cfg(feature = "checked")]
528 let dst_size = self.graph.resources[dst.index()].expect_buffer_info().size;
529
530 for region in regions.iter() {
531 #[cfg(feature = "checked")]
532 {
533 assert!(
534 region.src_offset + region.size <= src_size,
535 "source range end ({}) exceeds source size ({src_size})",
536 region.src_offset + region.size
537 );
538 assert!(
539 region.dst_offset + region.size <= dst_size,
540 "destination range end ({}) exceeds destination size ({dst_size})",
541 region.dst_offset + region.size
542 );
543 };
544
545 self.set_subresource_access(
546 src,
547 region.src_offset..region.src_offset + region.size,
548 AccessType::TransferRead,
549 );
550 self.set_subresource_access(
551 dst,
552 region.dst_offset..region.dst_offset + region.size,
553 AccessType::TransferWrite,
554 );
555 }
556
557 self.record_stream_mut(move |cmd| {
558 let src = cmd.resource(src);
559 let dst = cmd.resource(dst);
560
561 unsafe {
562 cmd.device
563 .cmd_copy_buffer(cmd.handle, src.handle, dst.handle, ®ions);
564 }
565 });
566 self
567 }
568
569 pub fn copy_buffer_to_image(
571 mut self,
572 src: impl Into<AnyBufferNode>,
573 dst: impl Into<AnyImageNode>,
574 regions: impl AsRef<[vk::BufferImageCopy]> + 'static + Send,
575 ) -> Self {
576 let src = src.into();
577 let dst = dst.into();
578 let dst_info = self.graph.resources[dst.index()].expect_image_info();
579 let regions = Arc::<[vk::BufferImageCopy]>::from(regions.as_ref());
580
581 for region in regions.iter() {
582 let block_bytes_size = format_texel_block_size(dst_info.format);
583 let (block_height, block_width) = format_texel_block_extent(dst_info.format);
584 let data_size = block_bytes_size
585 * (region.buffer_row_length / block_width)
586 * (region.buffer_image_height / block_height);
587
588 self.set_subresource_access(
589 src,
590 region.buffer_offset..region.buffer_offset + data_size as vk::DeviceSize,
591 AccessType::TransferRead,
592 );
593 self.set_subresource_access(
594 dst,
595 image_subresource_range_from_layers(region.image_subresource),
596 AccessType::TransferWrite,
597 );
598 }
599
600 self.record_stream_mut(move |cmd| {
601 let src = cmd.resource(src);
602 let dst = cmd.resource(dst);
603
604 unsafe {
605 cmd.device.cmd_copy_buffer_to_image(
606 cmd.handle,
607 src.handle,
608 dst.handle,
609 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
610 ®ions,
611 );
612 }
613 });
614 self
615 }
616
617 pub fn copy_image(
619 mut self,
620 src: impl Into<AnyImageNode>,
621 dst: impl Into<AnyImageNode>,
622 regions: impl AsRef<[vk::ImageCopy]> + 'static + Send,
623 ) -> Self {
624 let src = src.into();
625 let dst = dst.into();
626 let regions = Arc::<[vk::ImageCopy]>::from(regions.as_ref());
627
628 for region in regions.iter() {
629 self.set_subresource_access(
630 src,
631 image_subresource_range_from_layers(region.src_subresource),
632 AccessType::TransferRead,
633 );
634 self.set_subresource_access(
635 dst,
636 image_subresource_range_from_layers(region.dst_subresource),
637 AccessType::TransferWrite,
638 );
639 }
640
641 self.record_stream_mut(move |cmd| {
642 let src = cmd.resource(src);
643 let dst = cmd.resource(dst);
644
645 unsafe {
646 cmd.device.cmd_copy_image(
647 cmd.handle,
648 src.handle,
649 vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
650 dst.handle,
651 vk::ImageLayout::TRANSFER_DST_OPTIMAL,
652 ®ions,
653 );
654 }
655 });
656 self
657 }
658
659 pub fn copy_image_to_buffer(
661 mut self,
662 src: impl Into<AnyImageNode>,
663 dst: impl Into<AnyBufferNode>,
664 regions: impl AsRef<[vk::BufferImageCopy]> + 'static + Send,
665 ) -> Self {
666 let src = src.into();
667 let src_info = self.graph.resources[src.index()].expect_image_info();
668 let dst = dst.into();
669 let regions = Arc::<[vk::BufferImageCopy]>::from(regions.as_ref());
670
671 for region in regions.iter() {
672 let block_bytes_size = format_texel_block_size(src_info.format);
673 let (block_height, block_width) = format_texel_block_extent(src_info.format);
674 let data_size = block_bytes_size
675 * (region.buffer_row_length / block_width)
676 * (region.buffer_image_height / block_height);
677
678 self.set_subresource_access(
679 src,
680 image_subresource_range_from_layers(region.image_subresource),
681 AccessType::TransferRead,
682 );
683 self.set_subresource_access(
684 dst,
685 region.buffer_offset..region.buffer_offset + data_size as vk::DeviceSize,
686 AccessType::TransferWrite,
687 );
688 }
689
690 self.record_stream_mut(move |cmd| {
691 let src = cmd.resource(src);
692 let dst = cmd.resource(dst);
693
694 unsafe {
695 cmd.device.cmd_copy_image_to_buffer(
696 cmd.handle,
697 src.handle,
698 vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
699 dst.handle,
700 ®ions,
701 );
702 }
703 });
704 self
705 }
706
707 pub fn fill_buffer(
709 mut self,
710 buffer: impl Into<AnyBufferNode>,
711 region: Range<vk::DeviceSize>,
712 data: u32,
713 ) -> Self {
714 let buffer = buffer.into();
715
716 self.set_subresource_access(buffer, region.clone(), AccessType::TransferWrite);
717 self.record_stream_mut(move |cmd| {
718 let buffer = cmd.resource(buffer);
719
720 unsafe {
721 cmd.device.cmd_fill_buffer(
722 cmd.handle,
723 buffer.handle,
724 region.start,
725 region.end - region.start,
726 data,
727 );
728 }
729 });
730 self
731 }
732
733 pub(crate) fn record_stream(
734 mut self,
735 func: impl for<'r> Fn(CommandRef<'r>) + Send + Sync + 'static,
736 ) -> Self {
737 self.record_stream_mut(func);
738 self
739 }
740
741 pub(crate) fn record_stream_mut(
742 &mut self,
743 func: impl for<'r> Fn(CommandRef<'r>) + Send + Sync + 'static,
744 ) {
745 self.push_reusable_exec(func);
746 }
747
748 pub fn resource<N>(&self, resource_node: N) -> &N::Resource
751 where
752 N: Node,
753 {
754 self.graph.resource(resource_node)
755 }
756
757 pub fn resource_access<N>(mut self, resource_node: N, access: AccessType) -> Self
763 where
764 N: Node + Subresource,
765 SubresourceRange: From<N::Range>,
766 {
767 self.set_resource_access(resource_node, access);
768 self
769 }
770
771 pub fn set_debug_name(&mut self, name: impl Into<String>) -> &mut Self {
773 #[cfg(debug_assertions)]
774 {
775 self.cmd_mut().name = Some(name.into());
776 }
777
778 #[cfg(not(debug_assertions))]
779 {
780 let _ = name;
781 }
782
783 self
784 }
785
786 pub fn set_resource_access<N>(&mut self, resource_node: N, access: AccessType)
788 where
789 N: Node + Subresource,
790 SubresourceRange: From<N::Range>,
791 {
792 let whole_resource = resource_node.range(&self.graph.resources);
793 let subresource = SubresourceRange::from(whole_resource);
794
795 self.push_subresource_access(resource_node, subresource, access);
796 }
797
798 pub(crate) fn set_stream_scope_id(&mut self, stream_scope_id: u64) {
799 self.cmd_mut().stream_scope_id = Some(stream_scope_id);
800 }
801
802 pub fn set_subresource_access<N>(
804 &mut self,
805 resource_node: N,
806 subresource: impl Into<N::Range>,
807 access: AccessType,
808 ) where
809 N: Node + Subresource,
810 SubresourceRange: From<N::Range>,
811 {
812 let subresource = subresource.into();
813 let subresource = SubresourceRange::from(subresource);
814
815 self.push_subresource_access(resource_node, subresource, access);
816 }
817
818 pub fn subresource_access<N>(
824 mut self,
825 resource_node: N,
826 subresource: impl Into<N::Range>,
827 access: AccessType,
828 ) -> Self
829 where
830 N: Node + Subresource,
831 SubresourceRange: From<N::Range>,
832 {
833 self.set_subresource_access(resource_node, subresource, access);
834 self
835 }
836
837 #[profiling::function]
846 pub fn update_buffer(
847 mut self,
848 buffer: impl Into<AnyBufferNode>,
849 offset: vk::DeviceSize,
850 data: impl AsRef<[u8]> + 'static + Send,
851 ) -> Self {
852 debug_assert!(data.as_ref().len() <= 64 * 1024);
853
854 let buffer = buffer.into();
855 let data_end = offset + data.as_ref().len() as vk::DeviceSize;
856
857 #[cfg(feature = "checked")]
858 {
859 assert!(
860 data.as_ref().len() <= 64 * 1024,
861 "data length ({}) exceeds vkCmdUpdateBuffer limit (65536)",
862 data.as_ref().len()
863 );
864
865 let buffer_info = self.graph.resources[buffer.index()].expect_buffer_info();
866
867 assert!(
868 data_end <= buffer_info.size,
869 "data range end ({data_end}) exceeds buffer size ({})",
870 buffer_info.size
871 );
872 }
873
874 let data = Arc::<[u8]>::from(data.as_ref());
875
876 self.set_subresource_access(buffer, offset..data_end, AccessType::TransferWrite);
877 self.record_stream_mut(move |cmd| {
878 let buffer = cmd.resource(buffer);
879
880 unsafe {
881 cmd.device
882 .cmd_update_buffer(cmd.handle, buffer.handle, offset, &data);
883 }
884 });
885 self
886 }
887}
888
889#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
907pub struct Binding {
908 pub binding: u32,
910
911 pub offset: u32,
913
914 pub set: u32,
916}
917
918impl Binding {
919 pub(super) fn into_tuple(self) -> (DescriptorSetIndex, BindingIndex, BindingOffset) {
920 (self.set, self.binding, self.offset)
921 }
922
923 pub(super) fn set(self) -> DescriptorSetIndex {
924 let (res, _, _) = self.into_tuple();
925 res
926 }
927}
928
929impl From<BindingIndex> for Binding {
930 fn from(binding: BindingIndex) -> Self {
931 Self {
932 binding,
933 offset: 0,
934 set: 0,
935 }
936 }
937}
938
939impl From<(DescriptorSetIndex, BindingIndex)> for Binding {
940 fn from((set, binding): (DescriptorSetIndex, BindingIndex)) -> Self {
941 Self {
942 binding,
943 offset: 0,
944 set,
945 }
946 }
947}
948
949impl From<(BindingIndex, [BindingOffset; 1])> for Binding {
950 fn from((binding, [offset]): (BindingIndex, [BindingOffset; 1])) -> Self {
951 Self {
952 binding,
953 offset,
954 set: 0,
955 }
956 }
957}
958
959impl From<(DescriptorSetIndex, BindingIndex, [BindingOffset; 1])> for Binding {
960 fn from(
961 (set, binding, [offset]): (DescriptorSetIndex, BindingIndex, [BindingOffset; 1]),
962 ) -> Self {
963 Self {
964 binding,
965 offset,
966 set,
967 }
968 }
969}
970
971#[allow(private_bounds)]
973pub trait Subresource: private::SubresourceSealed {
974 type Info;
976
977 type Range;
979}
980
981macro_rules! view_accel_struct {
982 ($name:ty) => {
983 impl Subresource for $name {
984 type Info = Self::Range;
985 type Range = ();
986 }
987
988 impl private::SubresourceSealed for $name {
989 fn info(&self, _: &[AnyResource]) -> <Self as Subresource>::Info
990 where
991 Self: Node + Subresource,
992 {
993 }
994
995 fn range(&self, resources: &[AnyResource]) -> <Self as Subresource>::Range
996 where
997 Self: Node + Subresource,
998 {
999 resources[self.index()].expect_accel_struct_info();
1000 }
1001 }
1002 };
1003}
1004
1005view_accel_struct!(AnyAccelerationStructureNode);
1006view_accel_struct!(AccelerationStructureArg);
1007view_accel_struct!(AccelerationStructureLeaseNode);
1008view_accel_struct!(AccelerationStructureNode);
1009
1010macro_rules! view_buffer {
1011 ($name:ty) => {
1012 impl Subresource for $name {
1013 type Info = Self::Range;
1014 type Range = BufferSubresourceRange;
1015 }
1016
1017 impl private::SubresourceSealed for $name {
1018 fn info(&self, resources: &[AnyResource]) -> <Self as Subresource>::Info
1019 where
1020 Self: Node + Subresource,
1021 {
1022 self.range(resources)
1023 }
1024
1025 fn range(&self, resources: &[AnyResource]) -> <Self as Subresource>::Range
1026 where
1027 Self: Node + Subresource,
1028 {
1029 let idx = self.index();
1030
1031 resources[idx].expect_buffer_info().into()
1032 }
1033 }
1034 };
1035}
1036
1037view_buffer!(AnyBufferNode);
1038view_buffer!(BufferArg);
1039view_buffer!(BufferLeaseNode);
1040view_buffer!(BufferNode);
1041
1042macro_rules! view_image {
1043 ($name:ty) => {
1044 impl Subresource for $name {
1045 type Info = ImageViewInfo;
1046 type Range = vk::ImageSubresourceRange;
1047 }
1048
1049 impl private::SubresourceSealed for $name {
1050 fn info(&self, resources: &[AnyResource]) -> <Self as Subresource>::Info
1051 where
1052 Self: Node + Subresource,
1053 {
1054 let idx = self.index();
1055
1056 resources[idx].expect_image_info().into()
1057 }
1058
1059 fn range(&self, resources: &[AnyResource]) -> <Self as Subresource>::Range
1060 where
1061 Self: Node + Subresource,
1062 {
1063 self.info(resources).into()
1064 }
1065 }
1066 };
1067}
1068
1069view_image!(AnyImageNode);
1070view_image!(ImageArg);
1071view_image!(ImageLeaseNode);
1072view_image!(ImageNode);
1073view_image!(SwapchainImageNode);
1074
1075#[derive(Clone, Copy, Debug)]
1076pub(crate) enum SubresourceRange {
1077 AccelerationStructure,
1079
1080 Image(vk::ImageSubresourceRange),
1082
1083 Buffer(BufferSubresourceRange),
1085}
1086
1087impl SubresourceRange {
1088 pub(super) fn as_image(&self) -> Option<&vk::ImageSubresourceRange> {
1089 if let Self::Image(subresource) = self {
1090 Some(subresource)
1091 } else {
1092 None
1093 }
1094 }
1095
1096 pub(super) fn expect_image(&self) -> &vk::ImageSubresourceRange {
1097 self.as_image().expect("missing image subresource")
1098 }
1099}
1100
1101impl From<BufferSubresourceRange> for SubresourceRange {
1102 fn from(subresource: BufferSubresourceRange) -> Self {
1103 Self::Buffer(subresource)
1104 }
1105}
1106
1107impl From<()> for SubresourceRange {
1108 fn from(_: ()) -> Self {
1109 Self::AccelerationStructure
1110 }
1111}
1112
1113impl From<ImageViewInfo> for SubresourceRange {
1114 fn from(subresource: ImageViewInfo) -> Self {
1115 Self::Image(subresource.into())
1116 }
1117}
1118
1119impl From<vk::ImageSubresourceRange> for SubresourceRange {
1120 fn from(subresource: vk::ImageSubresourceRange) -> Self {
1121 Self::Image(subresource)
1122 }
1123}
1124
1125#[derive(Clone, Copy, Debug)]
1126pub(super) struct SubresourceAccess {
1127 pub access: AccessType,
1128 pub subresource: SubresourceRange,
1129}
1130
1131#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1133pub(crate) enum ViewInfo {
1134 AccelerationStructure,
1136
1137 Image(ImageViewInfo),
1139
1140 Buffer(BufferSubresourceRange),
1142}
1143
1144impl ViewInfo {
1145 pub(crate) fn as_buffer(&self) -> Option<&BufferSubresourceRange> {
1146 match self {
1147 Self::Buffer(info) => Some(info),
1148 _ => None,
1149 }
1150 }
1151
1152 pub(crate) fn as_image(&self) -> Option<&ImageViewInfo> {
1153 match self {
1154 Self::Image(info) => Some(info),
1155 _ => None,
1156 }
1157 }
1158
1159 pub(crate) fn expect_buffer(&self) -> &BufferSubresourceRange {
1160 self.as_buffer().expect("missing buffer view info")
1161 }
1162
1163 pub(crate) fn expect_image(&self) -> &ImageViewInfo {
1164 self.as_image().expect("missing image view info")
1165 }
1166}
1167
1168impl From<()> for ViewInfo {
1169 fn from(_: ()) -> Self {
1170 Self::AccelerationStructure
1171 }
1172}
1173
1174impl From<BufferSubresourceRange> for ViewInfo {
1175 fn from(info: BufferSubresourceRange) -> Self {
1176 Self::Buffer(info)
1177 }
1178}
1179
1180impl From<ImageViewInfo> for ViewInfo {
1181 fn from(info: ImageViewInfo) -> Self {
1182 Self::Image(info)
1183 }
1184}
1185
1186impl From<Range<vk::DeviceSize>> for ViewInfo {
1187 fn from(range: Range<vk::DeviceSize>) -> Self {
1188 Self::Buffer(BufferSubresourceRange {
1189 start: range.start,
1190 end: range.end,
1191 })
1192 }
1193}
1194
1195mod private {
1196 use crate::{AnyResource, Node};
1197
1198 pub(crate) trait SubresourceSealed: Sized {
1199 fn info(&self, resources: &[AnyResource]) -> <Self as super::Subresource>::Info
1200 where
1201 Self: Node + super::Subresource;
1202
1203 fn range(&self, resources: &[AnyResource]) -> <Self as super::Subresource>::Range
1204 where
1205 Self: Node + super::Subresource;
1206 }
1207}