atagen

monolith

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

Blame: crates/render-vk/tests/dmabuf.rs

7de49c2aa70batagen2026-10-16 09:27 UTC1
//! Dmabuf allocation, rendering, import and fence export. Skips on devices
7de49c2aa70batagen2026-10-16 09:27 UTC2
//! without dmabuf support, such as lavapipe inside the nix sandbox.
7de49c2aa70batagen2026-10-16 09:27 UTC3
7de49c2aa70batagen2026-10-16 09:27 UTC4
use monolith_render_vk::VulkanRenderer;
7de49c2aa70batagen2026-10-16 09:27 UTC5
use smithay::backend::allocator::dmabuf::Dmabuf;
7de49c2aa70batagen2026-10-16 09:27 UTC6
use smithay::backend::allocator::{Allocator, Fourcc, Modifier};
7de49c2aa70batagen2026-10-16 09:27 UTC7
use smithay::backend::renderer::{
7de49c2aa70batagen2026-10-16 09:27 UTC8
    Bind, Color32F, ExportMem, Frame, ImportDma, Offscreen, Renderer,
7de49c2aa70batagen2026-10-16 09:27 UTC9
};
7de49c2aa70batagen2026-10-16 09:27 UTC10
use smithay::utils::{Rectangle, Transform};
7de49c2aa70batagen2026-10-16 09:27 UTC11
7de49c2aa70batagen2026-10-16 09:27 UTC12
const SIZE: i32 = 32;
7de49c2aa70batagen2026-10-16 09:27 UTC13
7de49c2aa70batagen2026-10-16 09:27 UTC14
fn renderer() -> Option<VulkanRenderer> {
7de49c2aa70batagen2026-10-16 09:27 UTC15
    let r = VulkanRenderer::new().expect("no usable Vulkan device");
7de49c2aa70batagen2026-10-16 09:27 UTC16
    if !r.supports_dmabuf() {
7de49c2aa70batagen2026-10-16 09:27 UTC17
        eprintln!("skipping, {} cannot share dmabufs", r.device_name());
7de49c2aa70batagen2026-10-16 09:27 UTC18
        return None;
7de49c2aa70batagen2026-10-16 09:27 UTC19
    }
7de49c2aa70batagen2026-10-16 09:27 UTC20
    Some(r)
7de49c2aa70batagen2026-10-16 09:27 UTC21
}
7de49c2aa70batagen2026-10-16 09:27 UTC22
7de49c2aa70batagen2026-10-16 09:27 UTC23
fn dmabuf(r: &VulkanRenderer) -> Dmabuf {
7de49c2aa70batagen2026-10-16 09:27 UTC24
    let modifiers: Vec<Modifier> = r
7de49c2aa70batagen2026-10-16 09:27 UTC25
        .render_formats()
7de49c2aa70batagen2026-10-16 09:27 UTC26
        .iter()
7de49c2aa70batagen2026-10-16 09:27 UTC27
        .filter(|f| f.code == Fourcc::Argb8888)
7de49c2aa70batagen2026-10-16 09:27 UTC28
        .map(|f| f.modifier)
7de49c2aa70batagen2026-10-16 09:27 UTC29
        .collect();
7de49c2aa70batagen2026-10-16 09:27 UTC30
    r.allocator()
7de49c2aa70batagen2026-10-16 09:27 UTC31
        .create_buffer(SIZE as u32, SIZE as u32, Fourcc::Argb8888, &modifiers)
7de49c2aa70batagen2026-10-16 09:27 UTC32
        .unwrap()
7de49c2aa70batagen2026-10-16 09:27 UTC33
}
7de49c2aa70batagen2026-10-16 09:27 UTC34
7de49c2aa70batagen2026-10-16 09:27 UTC35
fn fill(
7de49c2aa70batagen2026-10-16 09:27 UTC36
    r: &mut VulkanRenderer,
7de49c2aa70batagen2026-10-16 09:27 UTC37
    buf: &mut Dmabuf,
7de49c2aa70batagen2026-10-16 09:27 UTC38
    colour: [f32; 4],
7de49c2aa70batagen2026-10-16 09:27 UTC39
) -> smithay::backend::renderer::sync::SyncPoint {
7de49c2aa70batagen2026-10-16 09:27 UTC40
    let mut target = r.bind(buf).unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC41
    let mut frame = r
7de49c2aa70batagen2026-10-16 09:27 UTC42
        .render(&mut target, (SIZE, SIZE).into(), Transform::Normal)
7de49c2aa70batagen2026-10-16 09:27 UTC43
        .unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC44
    frame
7de49c2aa70batagen2026-10-16 09:27 UTC45
        .clear(
7de49c2aa70batagen2026-10-16 09:27 UTC46
            Color32F::from(colour),
7de49c2aa70batagen2026-10-16 09:27 UTC47
            &[Rectangle::from_size((SIZE, SIZE).into())],
7de49c2aa70batagen2026-10-16 09:27 UTC48
        )
7de49c2aa70batagen2026-10-16 09:27 UTC49
        .unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC50
    frame.finish().unwrap()
7de49c2aa70batagen2026-10-16 09:27 UTC51
}
7de49c2aa70batagen2026-10-16 09:27 UTC52
7de49c2aa70batagen2026-10-16 09:27 UTC53
fn all_rgba(bytes: &[u8], want: [u8; 4]) -> bool {
7de49c2aa70batagen2026-10-16 09:27 UTC54
    bytes.as_chunks::<4>().0.iter().all(|p| *p == want)
7de49c2aa70batagen2026-10-16 09:27 UTC55
}
7de49c2aa70batagen2026-10-16 09:27 UTC56
7de49c2aa70batagen2026-10-16 09:27 UTC57
#[test]
7de49c2aa70batagen2026-10-16 09:27 UTC58
fn samples_an_imported_dmabuf() {
7de49c2aa70batagen2026-10-16 09:27 UTC59
    let Some(mut r) = renderer() else { return };
7de49c2aa70batagen2026-10-16 09:27 UTC60
    let mut buf = dmabuf(&r);
7de49c2aa70batagen2026-10-16 09:27 UTC61
    fill(&mut r, &mut buf, [0.0, 0.0, 1.0, 1.0]).wait().unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC62
    let texture = r.import_dmabuf(&buf, None).unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC63
    let mut out = r
7de49c2aa70batagen2026-10-16 09:27 UTC64
        .create_buffer(Fourcc::Argb8888, (SIZE, SIZE).into())
7de49c2aa70batagen2026-10-16 09:27 UTC65
        .unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC66
    let mut target = r.bind(&mut out).unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC67
    {
7de49c2aa70batagen2026-10-16 09:27 UTC68
        let full = Rectangle::from_size((SIZE, SIZE).into());
7de49c2aa70batagen2026-10-16 09:27 UTC69
        let mut frame = r
7de49c2aa70batagen2026-10-16 09:27 UTC70
            .render(&mut target, (SIZE, SIZE).into(), Transform::Normal)
7de49c2aa70batagen2026-10-16 09:27 UTC71
            .unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC72
        frame
7de49c2aa70batagen2026-10-16 09:27 UTC73
            .render_texture_from_to(
7de49c2aa70batagen2026-10-16 09:27 UTC74
                &texture,
7de49c2aa70batagen2026-10-16 09:27 UTC75
                Rectangle::from_size((SIZE as f64, SIZE as f64).into()),
7de49c2aa70batagen2026-10-16 09:27 UTC76
                full,
7de49c2aa70batagen2026-10-16 09:27 UTC77
                &[full],
7de49c2aa70batagen2026-10-16 09:27 UTC78
                &[],
7de49c2aa70batagen2026-10-16 09:27 UTC79
                Transform::Normal,
7de49c2aa70batagen2026-10-16 09:27 UTC80
                1.0,
7de49c2aa70batagen2026-10-16 09:27 UTC81
            )
7de49c2aa70batagen2026-10-16 09:27 UTC82
            .unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC83
        frame.finish().unwrap().wait().unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC84
    }
7de49c2aa70batagen2026-10-16 09:27 UTC85
    let mapping = r
7de49c2aa70batagen2026-10-16 09:27 UTC86
        .copy_framebuffer(
7de49c2aa70batagen2026-10-16 09:27 UTC87
            &target,
7de49c2aa70batagen2026-10-16 09:27 UTC88
            Rectangle::from_size((SIZE, SIZE).into()),
7de49c2aa70batagen2026-10-16 09:27 UTC89
            Fourcc::Abgr8888,
7de49c2aa70batagen2026-10-16 09:27 UTC90
        )
7de49c2aa70batagen2026-10-16 09:27 UTC91
        .unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC92
    assert!(all_rgba(r.map_texture(&mapping).unwrap(), [0, 0, 255, 255]));
7de49c2aa70batagen2026-10-16 09:27 UTC93
}
7de49c2aa70batagen2026-10-16 09:27 UTC94
7de49c2aa70batagen2026-10-16 09:27 UTC95
#[test]
7de49c2aa70batagen2026-10-16 09:27 UTC96
fn frame_fences_export_as_sync_files() {
7de49c2aa70batagen2026-10-16 09:27 UTC97
    let Some(mut r) = renderer() else { return };
7de49c2aa70batagen2026-10-16 09:27 UTC98
    let mut buf = dmabuf(&r);
7de49c2aa70batagen2026-10-16 09:27 UTC99
    let sync = fill(&mut r, &mut buf, [0.0, 1.0, 0.0, 1.0]);
7de49c2aa70batagen2026-10-16 09:27 UTC100
    assert!(sync.is_exportable());
7de49c2aa70batagen2026-10-16 09:27 UTC101
    let _fd = sync.export();
7de49c2aa70batagen2026-10-16 09:27 UTC102
    sync.wait().unwrap();
7de49c2aa70batagen2026-10-16 09:27 UTC103
    assert!(sync.is_reached());
7de49c2aa70batagen2026-10-16 09:27 UTC104
}