ursus_core/vulkan/core/
barrier.rs1use ash::vk;
2
3pub fn make_barrier_range(
4 image: vk::Image,
5 aspect_mask: vk::ImageAspectFlags,
6 base_mip_level: u32,
7 level_count: u32,
8 old_layout: vk::ImageLayout,
9 new_layout: vk::ImageLayout,
10) -> vk::ImageMemoryBarrier2<'static> {
11 let (src_stage, src_access, dst_stage, dst_access) = layout_transition_masks(old_layout, new_layout);
12
13 vk::ImageMemoryBarrier2::default()
14 .src_stage_mask(src_stage)
15 .src_access_mask(src_access)
16 .dst_stage_mask(dst_stage)
17 .dst_access_mask(dst_access)
18 .old_layout(old_layout)
19 .new_layout(new_layout)
20 .src_queue_family_index(vk::QUEUE_FAMILY_IGNORED)
21 .dst_queue_family_index(vk::QUEUE_FAMILY_IGNORED)
22 .image(image)
23 .subresource_range(vk::ImageSubresourceRange {
24 aspect_mask,
25 base_mip_level,
26 level_count,
27 base_array_layer: 0,
28 layer_count: 1,
29 })
30}
31
32fn stage_access(layout: vk::ImageLayout, is_src: bool) -> (vk::PipelineStageFlags2, vk::AccessFlags2) {
38 use vk::AccessFlags2 as A;
39 use vk::ImageLayout as L;
40 use vk::PipelineStageFlags2 as S;
41
42 match layout {
43 L::UNDEFINED => {
44 assert!(is_src, "UNDEFINED is only valid as the source (src) layout of a transition");
45 (S::TOP_OF_PIPE, A::empty())
46 }
47 L::PRESENT_SRC_KHR => {
48 if is_src {
49 (S::TOP_OF_PIPE, A::empty())
50 } else {
51 (S::BOTTOM_OF_PIPE, A::empty())
52 }
53 }
54 L::COLOR_ATTACHMENT_OPTIMAL => (S::COLOR_ATTACHMENT_OUTPUT, A::COLOR_ATTACHMENT_WRITE),
55 L::DEPTH_ATTACHMENT_OPTIMAL => {
56 if is_src {
59 (S::LATE_FRAGMENT_TESTS, A::DEPTH_STENCIL_ATTACHMENT_WRITE)
60 } else {
61 (S::EARLY_FRAGMENT_TESTS, A::DEPTH_STENCIL_ATTACHMENT_READ | A::DEPTH_STENCIL_ATTACHMENT_WRITE)
62 }
63 }
64 L::SHADER_READ_ONLY_OPTIMAL => (S::FRAGMENT_SHADER, A::SHADER_READ),
65 L::TRANSFER_SRC_OPTIMAL => (S::TRANSFER, A::TRANSFER_READ),
66 L::TRANSFER_DST_OPTIMAL => (S::TRANSFER, A::TRANSFER_WRITE),
67 other => panic!("stage_access: unsupported layout {:?}", other),
68 }
69}
70
71pub(crate) fn layout_transition_masks(
72 from: vk::ImageLayout,
73 to: vk::ImageLayout,
74) -> (vk::PipelineStageFlags2, vk::AccessFlags2, vk::PipelineStageFlags2, vk::AccessFlags2) {
75 let (src_stage, src_access) = stage_access(from, true);
76 let (dst_stage, dst_access) = stage_access(to, false);
77 (src_stage, src_access, dst_stage, dst_access)
78}