]> git.nega.tv - josh/narcissus/commitdiff
narcissus-gpu: Move vulkan barrier conversions to own module
authorJoshua Simmons <josh@nega.tv>
Mon, 17 Jul 2023 16:03:45 +0000 (18:03 +0200)
committerJoshua Simmons <josh@nega.tv>
Mon, 17 Jul 2023 16:03:45 +0000 (18:03 +0200)
libs/narcissus-gpu/src/backend/vulkan/barrier.rs [new file with mode: 0644]
libs/narcissus-gpu/src/backend/vulkan/mod.rs

diff --git a/libs/narcissus-gpu/src/backend/vulkan/barrier.rs b/libs/narcissus-gpu/src/backend/vulkan/barrier.rs
new file mode 100644 (file)
index 0000000..8d66b3f
--- /dev/null
@@ -0,0 +1,329 @@
+//! An alternative vulkan syncronization approach based on
+//! https://github.com/Tobski/simple_vulkan_synchronization
+
+use narcissus_core::default;
+use vulkan_sys as vk;
+
+use crate::{Access, GlobalBarrier, ImageBarrier, ImageLayout};
+
+pub struct VulkanAccessInfo {
+    stages: vk::PipelineStageFlags2,
+    access: vk::AccessFlags2,
+    layout: vk::ImageLayout,
+}
+
+#[must_use]
+pub fn vulkan_access_info(access: Access) -> VulkanAccessInfo {
+    match access {
+        Access::None => VulkanAccessInfo {
+            stages: default(),
+            access: default(),
+            layout: vk::ImageLayout::Undefined,
+        },
+
+        Access::IndirectBuffer => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::DRAW_INDIRECT,
+            access: vk::AccessFlags2::INDIRECT_COMMAND_READ,
+            layout: vk::ImageLayout::Undefined,
+        },
+        Access::IndexBuffer => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::VERTEX_INPUT,
+            access: vk::AccessFlags2::INDEX_READ,
+            layout: vk::ImageLayout::Undefined,
+        },
+        Access::VertexBuffer => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::VERTEX_INPUT,
+            access: vk::AccessFlags2::VERTEX_ATTRIBUTE_READ,
+            layout: vk::ImageLayout::Undefined,
+        },
+
+        Access::VertexShaderUniformBufferRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::VERTEX_SHADER,
+            access: vk::AccessFlags2::UNIFORM_READ,
+            layout: vk::ImageLayout::Undefined,
+        },
+        Access::VertexShaderSampledImageRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::VERTEX_SHADER,
+            access: vk::AccessFlags2::SHADER_READ,
+            layout: vk::ImageLayout::ReadOnlyOptimal,
+        },
+        Access::VertexShaderOtherRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::VERTEX_SHADER,
+            access: vk::AccessFlags2::SHADER_READ,
+            layout: vk::ImageLayout::General,
+        },
+
+        Access::FragmentShaderUniformBufferRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::FRAGMENT_SHADER,
+            access: vk::AccessFlags2::UNIFORM_READ,
+            layout: vk::ImageLayout::Undefined,
+        },
+        Access::FragmentShaderSampledImageRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::FRAGMENT_SHADER,
+            access: vk::AccessFlags2::SHADER_READ,
+            layout: vk::ImageLayout::ReadOnlyOptimal,
+        },
+        Access::FragmentShaderOtherRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::FRAGMENT_SHADER,
+            access: vk::AccessFlags2::SHADER_READ,
+            layout: vk::ImageLayout::General,
+        },
+
+        Access::ColorAttachmentRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
+            access: vk::AccessFlags2::COLOR_ATTACHMENT_READ,
+            layout: vk::ImageLayout::AttachmentOptimal,
+        },
+        Access::DepthStencilAttachmentRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
+            access: vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_READ,
+            layout: vk::ImageLayout::AttachmentOptimal,
+        },
+
+        Access::ShaderUniformBufferRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
+            access: vk::AccessFlags2::UNIFORM_READ,
+            layout: vk::ImageLayout::Undefined,
+        },
+        Access::ShaderUniformBufferOrVertexBufferRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
+            access: vk::AccessFlags2::UNIFORM_READ | vk::AccessFlags2::VERTEX_ATTRIBUTE_READ,
+            layout: vk::ImageLayout::Undefined,
+        },
+        Access::ShaderSampledImageRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
+            access: vk::AccessFlags2::SHADER_READ,
+            layout: vk::ImageLayout::ReadOnlyOptimal,
+        },
+        Access::ShaderOtherRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
+            access: vk::AccessFlags2::SHADER_READ,
+            layout: vk::ImageLayout::General,
+        },
+
+        Access::TransferRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::TRANSFER,
+            access: vk::AccessFlags2::TRANSFER_READ,
+            layout: vk::ImageLayout::TransferSrcOptimal,
+        },
+        Access::HostRead => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::HOST,
+            access: vk::AccessFlags2::HOST_READ,
+            layout: vk::ImageLayout::General,
+        },
+
+        Access::PresentRead => VulkanAccessInfo {
+            stages: default(),
+            access: default(),
+            layout: vk::ImageLayout::PresentSrcKhr,
+        },
+
+        Access::VertexShaderWrite => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::VERTEX_SHADER,
+            access: vk::AccessFlags2::SHADER_WRITE,
+            layout: vk::ImageLayout::General,
+        },
+        Access::FragmentShaderWrite => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::FRAGMENT_SHADER,
+            access: vk::AccessFlags2::SHADER_WRITE,
+            layout: vk::ImageLayout::General,
+        },
+        Access::ColorAttachmentWrite => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
+            access: vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
+            layout: vk::ImageLayout::ColorAttachmentOptimal,
+        },
+        Access::DepthStencilAttachmentWrite => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::EARLY_FRAGMENT_TESTS
+                | vk::PipelineStageFlags2::LATE_FRAGMENT_TESTS,
+            access: vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_WRITE,
+            layout: vk::ImageLayout::DepthAttachmentOptimal,
+        },
+        Access::ShaderWrite => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
+            access: vk::AccessFlags2::SHADER_WRITE,
+            layout: vk::ImageLayout::General,
+        },
+        Access::TransferWrite => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::TRANSFER,
+            access: vk::AccessFlags2::TRANSFER_WRITE,
+            layout: vk::ImageLayout::TransferDstOptimal,
+        },
+        Access::HostPreInitializedWrite => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::HOST,
+            access: vk::AccessFlags2::HOST_WRITE,
+            layout: vk::ImageLayout::Preinitialized,
+        },
+        Access::HostWrite => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::HOST,
+            access: vk::AccessFlags2::HOST_WRITE,
+            layout: vk::ImageLayout::General,
+        },
+        Access::ColorAttachmentReadWrite => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
+            access: vk::AccessFlags2::COLOR_ATTACHMENT_READ
+                | vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
+            layout: vk::ImageLayout::AttachmentOptimal,
+        },
+        Access::General => VulkanAccessInfo {
+            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
+            access: vk::AccessFlags2::COLOR_ATTACHMENT_READ
+                | vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
+            layout: vk::ImageLayout::General,
+        },
+    }
+}
+
+pub fn vulkan_memory_barrier(barrier: &GlobalBarrier) -> vk::MemoryBarrier2 {
+    let mut src_stage_mask = default();
+    let mut src_access_mask = default();
+    let mut dst_stage_mask = default();
+    let mut dst_access_mask = default();
+
+    for &access in barrier.prev_access {
+        debug_assert!(
+            access.is_read() || barrier.prev_access.len() == 1,
+            "write access types must be on their own"
+        );
+
+        let info = vulkan_access_info(access);
+        src_stage_mask |= info.stages;
+
+        // For writes, add availability operations.
+        if access.is_write() {
+            src_access_mask |= info.access;
+        }
+    }
+
+    for &access in barrier.next_access {
+        debug_assert!(
+            access.is_read() || barrier.prev_access.len() == 1,
+            "write access types must be on their own"
+        );
+
+        let info = vulkan_access_info(access);
+        dst_stage_mask |= info.stages;
+
+        // Add visibility operations if necessary.
+        //
+        // If the src access mask is zero, this is a write-after-read hazard (or for
+        // some reason, a read-after-read hazard), so the dst access mask can be safely
+        // zeroed as these don't need visibility.
+        if src_access_mask != default() {
+            dst_access_mask |= info.access;
+        }
+    }
+
+    if src_stage_mask == default() {
+        src_stage_mask = vk::PipelineStageFlags2::TOP_OF_PIPE;
+    }
+
+    if dst_stage_mask == default() {
+        dst_stage_mask = vk::PipelineStageFlags2::BOTTOM_OF_PIPE;
+    }
+
+    vk::MemoryBarrier2 {
+        src_stage_mask,
+        src_access_mask,
+        dst_stage_mask,
+        dst_access_mask,
+        ..default()
+    }
+}
+
+pub fn vulkan_image_memory_barrier(
+    barrier: &ImageBarrier,
+    image: vk::Image,
+    subresource_range: vk::ImageSubresourceRange,
+) -> vk::ImageMemoryBarrier2 {
+    let mut src_stage_mask = default();
+    let mut src_access_mask = default();
+    let mut dst_stage_mask = default();
+    let mut dst_access_mask = default();
+    let mut old_layout = vk::ImageLayout::Undefined;
+    let mut new_layout = vk::ImageLayout::Undefined;
+
+    for &access in barrier.prev_access {
+        debug_assert!(
+            access.is_read() || barrier.prev_access.len() == 1,
+            "write access types must be on their own"
+        );
+
+        let info = vulkan_access_info(access);
+        src_stage_mask |= info.stages;
+
+        // For writes, add availability operations.
+        if access.is_write() {
+            src_access_mask |= info.access;
+        }
+
+        let layout = match barrier.prev_layout {
+            ImageLayout::Optimal => info.layout,
+            ImageLayout::General => {
+                if access == Access::PresentRead {
+                    vk::ImageLayout::PresentSrcKhr
+                } else {
+                    vk::ImageLayout::General
+                }
+            }
+        };
+
+        debug_assert!(
+            old_layout == vk::ImageLayout::Undefined || old_layout == layout,
+            "mixed image layout"
+        );
+
+        old_layout = layout;
+    }
+
+    for &access in barrier.next_access {
+        debug_assert!(
+            access.is_read() || barrier.prev_access.len() == 1,
+            "write access types must be on their own"
+        );
+
+        let info = vulkan_access_info(access);
+        dst_stage_mask |= info.stages;
+
+        // Add visibility operations if necessary.
+        //
+        // If the src access mask is zero, this is a write-after-read hazard (or for
+        // some reason, a read-after-read hazard), so the dst access mask can be safely
+        // zeroed as these don't need visibility.
+        if src_access_mask != default() {
+            dst_access_mask |= info.access;
+        }
+
+        let layout = match barrier.next_layout {
+            ImageLayout::Optimal => info.layout,
+            ImageLayout::General => {
+                if access == Access::PresentRead {
+                    vk::ImageLayout::PresentSrcKhr
+                } else {
+                    vk::ImageLayout::General
+                }
+            }
+        };
+
+        debug_assert!(
+            new_layout == vk::ImageLayout::Undefined || new_layout == layout,
+            "mixed image layout"
+        );
+
+        new_layout = layout;
+    }
+
+    vk::ImageMemoryBarrier2 {
+        src_stage_mask,
+        src_access_mask,
+        dst_stage_mask,
+        dst_access_mask,
+        old_layout,
+        new_layout,
+        src_queue_family_index: 0,
+        dst_queue_family_index: 0,
+        image,
+        subresource_range,
+        ..default()
+    }
+}
index 31568f75c76ac67e88c07af13f2f731f4533acbb..b721c5d2b82dd6c838d600bf35975b15dba09fee 100644 (file)
@@ -18,7 +18,7 @@ use crate::{
     delay_queue::DelayQueue,
     frame_counter::FrameCounter,
     tlsf::{self, Tlsf},
-    Access, Bind, BindGroupLayout, BindGroupLayoutDesc, BindingType, BlendMode, Buffer, BufferArg,
+    Bind, BindGroupLayout, BindGroupLayoutDesc, BindingType, BlendMode, Buffer, BufferArg,
     BufferDesc, BufferImageCopy, BufferUsageFlags, ClearValue, CmdBuffer, CompareOp,
     ComputePipelineDesc, CullingMode, Device, Extent2d, Extent3d, Frame, FrontFace, GlobalBarrier,
     GpuConcurrent, GraphicsPipelineDesc, Image, ImageAspectFlags, ImageBarrier, ImageBlit,
@@ -29,10 +29,14 @@ use crate::{
     SwapchainOutOfDateError, ThreadToken, Topology, TransientBuffer, TypedBind,
 };
 
+mod barrier;
 mod libc;
 mod wsi;
 
-use self::wsi::{VulkanWsi, VulkanWsiFrame};
+use self::{
+    barrier::{vulkan_image_memory_barrier, vulkan_memory_barrier},
+    wsi::{VulkanWsi, VulkanWsiFrame},
+};
 
 /// Important constant data configuration for the vulkan backend.
 pub struct VulkanConstants {
@@ -452,328 +456,6 @@ fn vulkan_shader_module(
     shader_module
 }
 
-struct VulkanAccessInfo {
-    stages: vk::PipelineStageFlags2,
-    access: vk::AccessFlags2,
-    layout: vk::ImageLayout,
-}
-
-#[must_use]
-fn vulkan_access_info(access: Access) -> VulkanAccessInfo {
-    match access {
-        Access::None => VulkanAccessInfo {
-            stages: default(),
-            access: default(),
-            layout: vk::ImageLayout::Undefined,
-        },
-
-        Access::IndirectBuffer => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::DRAW_INDIRECT,
-            access: vk::AccessFlags2::INDIRECT_COMMAND_READ,
-            layout: vk::ImageLayout::Undefined,
-        },
-        Access::IndexBuffer => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::VERTEX_INPUT,
-            access: vk::AccessFlags2::INDEX_READ,
-            layout: vk::ImageLayout::Undefined,
-        },
-        Access::VertexBuffer => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::VERTEX_INPUT,
-            access: vk::AccessFlags2::VERTEX_ATTRIBUTE_READ,
-            layout: vk::ImageLayout::Undefined,
-        },
-
-        Access::VertexShaderUniformBufferRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::VERTEX_SHADER,
-            access: vk::AccessFlags2::UNIFORM_READ,
-            layout: vk::ImageLayout::Undefined,
-        },
-        Access::VertexShaderSampledImageRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::VERTEX_SHADER,
-            access: vk::AccessFlags2::SHADER_READ,
-            layout: vk::ImageLayout::ReadOnlyOptimal,
-        },
-        Access::VertexShaderOtherRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::VERTEX_SHADER,
-            access: vk::AccessFlags2::SHADER_READ,
-            layout: vk::ImageLayout::General,
-        },
-
-        Access::FragmentShaderUniformBufferRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::FRAGMENT_SHADER,
-            access: vk::AccessFlags2::UNIFORM_READ,
-            layout: vk::ImageLayout::Undefined,
-        },
-        Access::FragmentShaderSampledImageRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::FRAGMENT_SHADER,
-            access: vk::AccessFlags2::SHADER_READ,
-            layout: vk::ImageLayout::ReadOnlyOptimal,
-        },
-        Access::FragmentShaderOtherRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::FRAGMENT_SHADER,
-            access: vk::AccessFlags2::SHADER_READ,
-            layout: vk::ImageLayout::General,
-        },
-
-        Access::ColorAttachmentRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
-            access: vk::AccessFlags2::COLOR_ATTACHMENT_READ,
-            layout: vk::ImageLayout::AttachmentOptimal,
-        },
-        Access::DepthStencilAttachmentRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
-            access: vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_READ,
-            layout: vk::ImageLayout::AttachmentOptimal,
-        },
-
-        Access::ShaderUniformBufferRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
-            access: vk::AccessFlags2::UNIFORM_READ,
-            layout: vk::ImageLayout::Undefined,
-        },
-        Access::ShaderUniformBufferOrVertexBufferRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
-            access: vk::AccessFlags2::UNIFORM_READ | vk::AccessFlags2::VERTEX_ATTRIBUTE_READ,
-            layout: vk::ImageLayout::Undefined,
-        },
-        Access::ShaderSampledImageRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
-            access: vk::AccessFlags2::SHADER_READ,
-            layout: vk::ImageLayout::ReadOnlyOptimal,
-        },
-        Access::ShaderOtherRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
-            access: vk::AccessFlags2::SHADER_READ,
-            layout: vk::ImageLayout::General,
-        },
-
-        Access::TransferRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::TRANSFER,
-            access: vk::AccessFlags2::TRANSFER_READ,
-            layout: vk::ImageLayout::TransferSrcOptimal,
-        },
-        Access::HostRead => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::HOST,
-            access: vk::AccessFlags2::HOST_READ,
-            layout: vk::ImageLayout::General,
-        },
-
-        Access::PresentRead => VulkanAccessInfo {
-            stages: default(),
-            access: default(),
-            layout: vk::ImageLayout::PresentSrcKhr,
-        },
-
-        Access::VertexShaderWrite => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::VERTEX_SHADER,
-            access: vk::AccessFlags2::SHADER_WRITE,
-            layout: vk::ImageLayout::General,
-        },
-        Access::FragmentShaderWrite => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::FRAGMENT_SHADER,
-            access: vk::AccessFlags2::SHADER_WRITE,
-            layout: vk::ImageLayout::General,
-        },
-        Access::ColorAttachmentWrite => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
-            access: vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
-            layout: vk::ImageLayout::ColorAttachmentOptimal,
-        },
-        Access::DepthStencilAttachmentWrite => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::EARLY_FRAGMENT_TESTS
-                | vk::PipelineStageFlags2::LATE_FRAGMENT_TESTS,
-            access: vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_WRITE,
-            layout: vk::ImageLayout::DepthAttachmentOptimal,
-        },
-        Access::ShaderWrite => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
-            access: vk::AccessFlags2::SHADER_WRITE,
-            layout: vk::ImageLayout::General,
-        },
-        Access::TransferWrite => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::TRANSFER,
-            access: vk::AccessFlags2::TRANSFER_WRITE,
-            layout: vk::ImageLayout::TransferDstOptimal,
-        },
-        Access::HostPreInitializedWrite => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::HOST,
-            access: vk::AccessFlags2::HOST_WRITE,
-            layout: vk::ImageLayout::Preinitialized,
-        },
-        Access::HostWrite => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::HOST,
-            access: vk::AccessFlags2::HOST_WRITE,
-            layout: vk::ImageLayout::General,
-        },
-        Access::ColorAttachmentReadWrite => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
-            access: vk::AccessFlags2::COLOR_ATTACHMENT_READ
-                | vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
-            layout: vk::ImageLayout::AttachmentOptimal,
-        },
-        Access::General => VulkanAccessInfo {
-            stages: vk::PipelineStageFlags2::ALL_COMMANDS,
-            access: vk::AccessFlags2::COLOR_ATTACHMENT_READ
-                | vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
-            layout: vk::ImageLayout::General,
-        },
-    }
-}
-
-fn vulkan_memory_barrier(barrier: &GlobalBarrier) -> vk::MemoryBarrier2 {
-    let mut src_stage_mask = default();
-    let mut src_access_mask = default();
-    let mut dst_stage_mask = default();
-    let mut dst_access_mask = default();
-
-    for &access in barrier.prev_access {
-        debug_assert!(
-            access.is_read() || barrier.prev_access.len() == 1,
-            "write access types must be on their own"
-        );
-
-        let info = vulkan_access_info(access);
-        src_stage_mask |= info.stages;
-
-        // For writes, add availability operations.
-        if access.is_write() {
-            src_access_mask |= info.access;
-        }
-    }
-
-    for &access in barrier.next_access {
-        debug_assert!(
-            access.is_read() || barrier.prev_access.len() == 1,
-            "write access types must be on their own"
-        );
-
-        let info = vulkan_access_info(access);
-        dst_stage_mask |= info.stages;
-
-        // Add visibility operations if necessary.
-        //
-        // If the src access mask is zero, this is a Write-After-Read hazard (or for some reason, a
-        // Read-After-Read), so the dst access mask can be safely zeroed as these don't need
-        // visibility.
-        if src_access_mask != default() {
-            dst_access_mask |= info.access;
-        }
-    }
-
-    if src_stage_mask == default() {
-        src_stage_mask = vk::PipelineStageFlags2::TOP_OF_PIPE;
-    }
-
-    if dst_stage_mask == default() {
-        dst_stage_mask = vk::PipelineStageFlags2::BOTTOM_OF_PIPE;
-    }
-
-    vk::MemoryBarrier2 {
-        src_stage_mask,
-        src_access_mask,
-        dst_stage_mask,
-        dst_access_mask,
-        ..default()
-    }
-}
-
-fn vulkan_image_memory_barrier(
-    barrier: &ImageBarrier,
-    image: vk::Image,
-    subresource_range: vk::ImageSubresourceRange,
-) -> vk::ImageMemoryBarrier2 {
-    let mut src_stage_mask = default();
-    let mut src_access_mask = default();
-    let mut dst_stage_mask = default();
-    let mut dst_access_mask = default();
-    let mut old_layout = vk::ImageLayout::Undefined;
-    let mut new_layout = vk::ImageLayout::Undefined;
-
-    for &access in barrier.prev_access {
-        debug_assert!(
-            access.is_read() || barrier.prev_access.len() == 1,
-            "write access types must be on their own"
-        );
-
-        let info = vulkan_access_info(access);
-        src_stage_mask |= info.stages;
-
-        // For writes, add availability operations.
-        if access.is_write() {
-            src_access_mask |= info.access;
-        }
-
-        let layout = match barrier.prev_layout {
-            ImageLayout::Optimal => info.layout,
-            ImageLayout::General => {
-                if access == Access::PresentRead {
-                    vk::ImageLayout::PresentSrcKhr
-                } else {
-                    vk::ImageLayout::General
-                }
-            }
-        };
-
-        debug_assert!(
-            old_layout == vk::ImageLayout::Undefined || old_layout == layout,
-            "mixed image layout"
-        );
-
-        old_layout = layout;
-    }
-
-    for &access in barrier.next_access {
-        debug_assert!(
-            access.is_read() || barrier.prev_access.len() == 1,
-            "write access types must be on their own"
-        );
-
-        let info = vulkan_access_info(access);
-        dst_stage_mask |= info.stages;
-
-        // Add visibility operations if necessary.
-        //
-        // If the src access mask is zero, this is a Write-After-Read hazard (or for
-        // some reason, a Read-After-Read), so the dst access mask can be safely zeroed
-        // as these don't need visibility.
-        if src_access_mask != default() {
-            dst_access_mask |= info.access;
-        }
-
-        let layout = match barrier.next_layout {
-            ImageLayout::Optimal => info.layout,
-            ImageLayout::General => {
-                if access == Access::PresentRead {
-                    vk::ImageLayout::PresentSrcKhr
-                } else {
-                    vk::ImageLayout::General
-                }
-            }
-        };
-
-        debug_assert!(
-            new_layout == vk::ImageLayout::Undefined || new_layout == layout,
-            "mixed image layout"
-        );
-
-        new_layout = layout;
-    }
-
-    vk::ImageMemoryBarrier2 {
-        src_stage_mask,
-        src_access_mask,
-        dst_stage_mask,
-        dst_access_mask,
-        old_layout,
-        new_layout,
-        src_queue_family_index: 0,
-        dst_queue_family_index: 0,
-        image,
-        subresource_range,
-        ..default()
-    }
-}
-
 struct VulkanBuffer {
     memory: VulkanMemory,
     buffer: vk::Buffer,