atagen

monolith

public
Star0
Watch0
29e5c25cd383486684c571c229f151c4b189bf7f
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git

Blame: crates/render-vk/src/barrier.rs

de1e9f21296catagen2026-10-17 04:49 UTC1
use crate::image::{ImageInner, color_range};
de1e9f21296catagen2026-10-17 04:49 UTC2
use ash::vk;
ad1f04ba8cb2atagen2026-10-19 07:30 UTC3
use std::sync::Arc;
ad1f04ba8cb2atagen2026-10-19 07:30 UTC4
ad1f04ba8cb2atagen2026-10-19 07:30 UTC5
/// Layout changes recorded into a command buffer that has not been submitted.
ad1f04ba8cb2atagen2026-10-19 07:30 UTC6
/// Images keep their old layout until `commit`, so a failed submit leaves the
ad1f04ba8cb2atagen2026-10-19 07:30 UTC7
/// tracking true to what the GPU has done.
ad1f04ba8cb2atagen2026-10-19 07:30 UTC8
#[derive(Default)]
ad1f04ba8cb2atagen2026-10-19 07:30 UTC9
pub(crate) struct LayoutLog(Vec<(Arc<ImageInner>, vk::ImageLayout)>);
ad1f04ba8cb2atagen2026-10-19 07:30 UTC10
ad1f04ba8cb2atagen2026-10-19 07:30 UTC11
impl LayoutLog {
ad1f04ba8cb2atagen2026-10-19 07:30 UTC12
    fn current(&self, image: &Arc<ImageInner>) -> vk::ImageLayout {
ad1f04ba8cb2atagen2026-10-19 07:30 UTC13
        self.0
ad1f04ba8cb2atagen2026-10-19 07:30 UTC14
            .iter()
ad1f04ba8cb2atagen2026-10-19 07:30 UTC15
            .rev()
ad1f04ba8cb2atagen2026-10-19 07:30 UTC16
            .find(|(i, _)| Arc::ptr_eq(i, image))
ad1f04ba8cb2atagen2026-10-19 07:30 UTC17
            .map_or_else(|| image.layout(), |(_, layout)| *layout)
ad1f04ba8cb2atagen2026-10-19 07:30 UTC18
    }
ad1f04ba8cb2atagen2026-10-19 07:30 UTC19
ad1f04ba8cb2atagen2026-10-19 07:30 UTC20
    pub fn commit(self) {
ad1f04ba8cb2atagen2026-10-19 07:30 UTC21
        for (image, layout) in self.0 {
ad1f04ba8cb2atagen2026-10-19 07:30 UTC22
            image.set_layout(layout);
ad1f04ba8cb2atagen2026-10-19 07:30 UTC23
        }
ad1f04ba8cb2atagen2026-10-19 07:30 UTC24
    }
ad1f04ba8cb2atagen2026-10-19 07:30 UTC25
}
de1e9f21296catagen2026-10-17 04:49 UTC26
d2f26399309batagen2026-10-19 07:32 UTC27
struct Scope {
d2f26399309batagen2026-10-19 07:32 UTC28
    stage: vk::PipelineStageFlags2,
d2f26399309batagen2026-10-19 07:32 UTC29
    access: vk::AccessFlags2,
d2f26399309batagen2026-10-19 07:32 UTC30
}
d2f26399309batagen2026-10-19 07:32 UTC31
d2f26399309batagen2026-10-19 07:32 UTC32
/// What an image may still be doing when it leaves `layout`. Layouts the
d2f26399309batagen2026-10-19 07:32 UTC33
/// renderer does not use itself, the general layout of dmabufs among them,
d2f26399309batagen2026-10-19 07:32 UTC34
/// wait for everything.
d2f26399309batagen2026-10-19 07:32 UTC35
fn leaving(layout: vk::ImageLayout) -> Scope {
d2f26399309batagen2026-10-19 07:32 UTC36
    let (stage, access) = match layout {
d2f26399309batagen2026-10-19 07:32 UTC37
        vk::ImageLayout::UNDEFINED => (vk::PipelineStageFlags2::NONE, vk::AccessFlags2::NONE),
d2f26399309batagen2026-10-19 07:32 UTC38
        vk::ImageLayout::TRANSFER_DST_OPTIMAL => (
d2f26399309batagen2026-10-19 07:32 UTC39
            vk::PipelineStageFlags2::TRANSFER,
d2f26399309batagen2026-10-19 07:32 UTC40
            vk::AccessFlags2::TRANSFER_WRITE,
d2f26399309batagen2026-10-19 07:32 UTC41
        ),
d2f26399309batagen2026-10-19 07:32 UTC42
        vk::ImageLayout::TRANSFER_SRC_OPTIMAL => {
d2f26399309batagen2026-10-19 07:32 UTC43
            (vk::PipelineStageFlags2::TRANSFER, vk::AccessFlags2::NONE)
d2f26399309batagen2026-10-19 07:32 UTC44
        }
d2f26399309batagen2026-10-19 07:32 UTC45
        vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL => (
d2f26399309batagen2026-10-19 07:32 UTC46
            vk::PipelineStageFlags2::FRAGMENT_SHADER,
d2f26399309batagen2026-10-19 07:32 UTC47
            vk::AccessFlags2::NONE,
d2f26399309batagen2026-10-19 07:32 UTC48
        ),
d2f26399309batagen2026-10-19 07:32 UTC49
        vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL => (
d2f26399309batagen2026-10-19 07:32 UTC50
            vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
d2f26399309batagen2026-10-19 07:32 UTC51
            vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
d2f26399309batagen2026-10-19 07:32 UTC52
        ),
d2f26399309batagen2026-10-19 07:32 UTC53
        _ => (
d2f26399309batagen2026-10-19 07:32 UTC54
            vk::PipelineStageFlags2::ALL_COMMANDS,
d2f26399309batagen2026-10-19 07:32 UTC55
            vk::AccessFlags2::MEMORY_WRITE,
d2f26399309batagen2026-10-19 07:32 UTC56
        ),
de1e9f21296catagen2026-10-17 04:49 UTC57
    };
d2f26399309batagen2026-10-19 07:32 UTC58
    Scope { stage, access }
de1e9f21296catagen2026-10-17 04:49 UTC59
}
de1e9f21296catagen2026-10-17 04:49 UTC60
d2f26399309batagen2026-10-19 07:32 UTC61
/// What an image does once it is in `layout`.
d2f26399309batagen2026-10-19 07:32 UTC62
fn entering(layout: vk::ImageLayout) -> Scope {
d2f26399309batagen2026-10-19 07:32 UTC63
    let (stage, access) = match layout {
d2f26399309batagen2026-10-19 07:32 UTC64
        vk::ImageLayout::TRANSFER_DST_OPTIMAL => (
d2f26399309batagen2026-10-19 07:32 UTC65
            vk::PipelineStageFlags2::TRANSFER,
d2f26399309batagen2026-10-19 07:32 UTC66
            vk::AccessFlags2::TRANSFER_WRITE,
d2f26399309batagen2026-10-19 07:32 UTC67
        ),
d2f26399309batagen2026-10-19 07:32 UTC68
        vk::ImageLayout::TRANSFER_SRC_OPTIMAL => (
d2f26399309batagen2026-10-19 07:32 UTC69
            vk::PipelineStageFlags2::TRANSFER,
d2f26399309batagen2026-10-19 07:32 UTC70
            vk::AccessFlags2::TRANSFER_READ,
d2f26399309batagen2026-10-19 07:32 UTC71
        ),
d2f26399309batagen2026-10-19 07:32 UTC72
        vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL => (
d2f26399309batagen2026-10-19 07:32 UTC73
            vk::PipelineStageFlags2::FRAGMENT_SHADER,
d2f26399309batagen2026-10-19 07:32 UTC74
            vk::AccessFlags2::SHADER_SAMPLED_READ,
d2f26399309batagen2026-10-19 07:32 UTC75
        ),
d2f26399309batagen2026-10-19 07:32 UTC76
        vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL => (
d2f26399309batagen2026-10-19 07:32 UTC77
            vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
d2f26399309batagen2026-10-19 07:32 UTC78
            vk::AccessFlags2::COLOR_ATTACHMENT_READ | vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
d2f26399309batagen2026-10-19 07:32 UTC79
        ),
d2f26399309batagen2026-10-19 07:32 UTC80
        _ => (
d2f26399309batagen2026-10-19 07:32 UTC81
            vk::PipelineStageFlags2::ALL_COMMANDS,
d2f26399309batagen2026-10-19 07:32 UTC82
            vk::AccessFlags2::MEMORY_READ | vk::AccessFlags2::MEMORY_WRITE,
d2f26399309batagen2026-10-19 07:32 UTC83
        ),
d2f26399309batagen2026-10-19 07:32 UTC84
    };
d2f26399309batagen2026-10-19 07:32 UTC85
    Scope { stage, access }
d2f26399309batagen2026-10-19 07:32 UTC86
}
d2f26399309batagen2026-10-19 07:32 UTC87
d2f26399309batagen2026-10-19 07:32 UTC88
/// The image barriers of one phase of a command buffer, recorded together.
d2f26399309batagen2026-10-19 07:32 UTC89
#[derive(Default)]
d2f26399309batagen2026-10-19 07:32 UTC90
pub(crate) struct Barriers(Vec<vk::ImageMemoryBarrier2<'static>>);
d2f26399309batagen2026-10-19 07:32 UTC91
d2f26399309batagen2026-10-19 07:32 UTC92
impl Barriers {
d2f26399309batagen2026-10-19 07:32 UTC93
    fn push(
d2f26399309batagen2026-10-19 07:32 UTC94
        &mut self,
d2f26399309batagen2026-10-19 07:32 UTC95
        image: vk::Image,
d2f26399309batagen2026-10-19 07:32 UTC96
        (old, src_family): (vk::ImageLayout, u32),
d2f26399309batagen2026-10-19 07:32 UTC97
        (new, dst_family): (vk::ImageLayout, u32),
d2f26399309batagen2026-10-19 07:32 UTC98
    ) {
d2f26399309batagen2026-10-19 07:32 UTC99
        let (from, to) = (leaving(old), entering(new));
d2f26399309batagen2026-10-19 07:32 UTC100
        self.0.push(
d2f26399309batagen2026-10-19 07:32 UTC101
            vk::ImageMemoryBarrier2::default()
d2f26399309batagen2026-10-19 07:32 UTC102
                .src_stage_mask(from.stage)
d2f26399309batagen2026-10-19 07:32 UTC103
                .src_access_mask(from.access)
d2f26399309batagen2026-10-19 07:32 UTC104
                .dst_stage_mask(to.stage)
d2f26399309batagen2026-10-19 07:32 UTC105
                .dst_access_mask(to.access)
d2f26399309batagen2026-10-19 07:32 UTC106
                .old_layout(old)
d2f26399309batagen2026-10-19 07:32 UTC107
                .new_layout(new)
d2f26399309batagen2026-10-19 07:32 UTC108
                .src_queue_family_index(src_family)
d2f26399309batagen2026-10-19 07:32 UTC109
                .dst_queue_family_index(dst_family)
d2f26399309batagen2026-10-19 07:32 UTC110
                .image(image)
d2f26399309batagen2026-10-19 07:32 UTC111
                .subresource_range(color_range()),
d2f26399309batagen2026-10-19 07:32 UTC112
        );
d2f26399309batagen2026-10-19 07:32 UTC113
    }
d2f26399309batagen2026-10-19 07:32 UTC114
d2f26399309batagen2026-10-19 07:32 UTC115
    /// Moves an image into `layout` for use on this queue. Dmabuf images come
d2f26399309batagen2026-10-19 07:32 UTC116
    /// from the foreign queue family in the general layout, others continue
d2f26399309batagen2026-10-19 07:32 UTC117
    /// from their tracked layout.
d2f26399309batagen2026-10-19 07:32 UTC118
    pub fn acquire(
d2f26399309batagen2026-10-19 07:32 UTC119
        &mut self,
d2f26399309batagen2026-10-19 07:32 UTC120
        family: u32,
d2f26399309batagen2026-10-19 07:32 UTC121
        image: &Arc<ImageInner>,
d2f26399309batagen2026-10-19 07:32 UTC122
        layout: vk::ImageLayout,
d2f26399309batagen2026-10-19 07:32 UTC123
        log: &mut LayoutLog,
d2f26399309batagen2026-10-19 07:32 UTC124
    ) {
d2f26399309batagen2026-10-19 07:32 UTC125
        if image.external {
d2f26399309batagen2026-10-19 07:32 UTC126
            self.push(
de1e9f21296catagen2026-10-17 04:49 UTC127
                image.image,
d2f26399309batagen2026-10-19 07:32 UTC128
                (vk::ImageLayout::GENERAL, vk::QUEUE_FAMILY_FOREIGN_EXT),
d2f26399309batagen2026-10-19 07:32 UTC129
                (layout, family),
d2f26399309batagen2026-10-19 07:32 UTC130
            );
d2f26399309batagen2026-10-19 07:32 UTC131
        } else {
d2f26399309batagen2026-10-19 07:32 UTC132
            let old = log.current(image);
d2f26399309batagen2026-10-19 07:32 UTC133
            if old != layout {
d2f26399309batagen2026-10-19 07:32 UTC134
                self.push(
de1e9f21296catagen2026-10-17 04:49 UTC135
                    image.image,
d2f26399309batagen2026-10-19 07:32 UTC136
                    (old, vk::QUEUE_FAMILY_IGNORED),
d2f26399309batagen2026-10-19 07:32 UTC137
                    (layout, vk::QUEUE_FAMILY_IGNORED),
d2f26399309batagen2026-10-19 07:32 UTC138
                );
d2f26399309batagen2026-10-19 07:32 UTC139
                log.0.push((image.clone(), layout));
d2f26399309batagen2026-10-19 07:32 UTC140
            }
d2f26399309batagen2026-10-19 07:32 UTC141
        }
d2f26399309batagen2026-10-19 07:32 UTC142
    }
d2f26399309batagen2026-10-19 07:32 UTC143
d2f26399309batagen2026-10-19 07:32 UTC144
    /// Hands a dmabuf image back to the foreign queue family after use.
d2f26399309batagen2026-10-19 07:32 UTC145
    pub fn release(&mut self, family: u32, image: &ImageInner, layout: vk::ImageLayout) {
d2f26399309batagen2026-10-19 07:32 UTC146
        if image.external {
d2f26399309batagen2026-10-19 07:32 UTC147
            self.push(
d2f26399309batagen2026-10-19 07:32 UTC148
                image.image,
d2f26399309batagen2026-10-19 07:32 UTC149
                (layout, family),
d2f26399309batagen2026-10-19 07:32 UTC150
                (vk::ImageLayout::GENERAL, vk::QUEUE_FAMILY_FOREIGN_EXT),
d2f26399309batagen2026-10-19 07:32 UTC151
            );
de1e9f21296catagen2026-10-17 04:49 UTC152
        }
de1e9f21296catagen2026-10-17 04:49 UTC153
    }
de1e9f21296catagen2026-10-17 04:49 UTC154
d2f26399309batagen2026-10-19 07:32 UTC155
    pub unsafe fn record(self, d: &ash::Device, cmd: vk::CommandBuffer) {
d2f26399309batagen2026-10-19 07:32 UTC156
        if self.0.is_empty() {
d2f26399309batagen2026-10-19 07:32 UTC157
            return;
d2f26399309batagen2026-10-19 07:32 UTC158
        }
de1e9f21296catagen2026-10-17 04:49 UTC159
        unsafe {
d2f26399309batagen2026-10-19 07:32 UTC160
            d.cmd_pipeline_barrier2(
de1e9f21296catagen2026-10-17 04:49 UTC161
                cmd,
d2f26399309batagen2026-10-19 07:32 UTC162
                &vk::DependencyInfo::default().image_memory_barriers(&self.0),
de1e9f21296catagen2026-10-17 04:49 UTC163
            )
de1e9f21296catagen2026-10-17 04:49 UTC164
        };
de1e9f21296catagen2026-10-17 04:49 UTC165
    }
de1e9f21296catagen2026-10-17 04:49 UTC166
}