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