hbm 0.1.6

A hardware buffer allocator
Documentation
use drm_fourcc::DrmFourcc;
use hbm::{Flags, Format, MemoryType, Usage};
use std::slice;
use std::sync::Arc;

#[cfg(feature = "ash")]
fn test_image(dev: Arc<hbm::Device>) {
    let img_desc = hbm::Description::new()
        .flags(Flags::EXTERNAL | Flags::MAP | Flags::COPY)
        .format(Format(DrmFourcc::Argb8888 as u32));
    let img_usage = Usage::Vulkan(hbm::vulkan::Usage::empty());
    let img_class = dev.classify(img_desc, slice::from_ref(&img_usage)).unwrap();

    let img_width = 63;
    let img_height = 63;
    let mut img_bo = hbm::Bo::with_constraint(
        dev.clone(),
        &img_class,
        hbm::Extent::Image(img_width, img_height),
        None,
    )
    .unwrap();
    img_bo.bind_memory(MemoryType::MAPPABLE, None).unwrap();

    let img_dmabuf = img_bo.export_dma_buf(Some("img")).unwrap();
    let img_layout = img_bo.layout();
    println!(
        "img size {}x{} alloc {} format {} modifier 0x{:x}",
        img_width, img_height, img_layout.size, img_desc.format, img_layout.modifier.0,
    );
    for plane in 0..(img_layout.plane_count as usize) {
        println!(
            "  plane {}: offset {} stride {}",
            plane, img_layout.offsets[plane], img_layout.strides[plane]
        );
    }

    let mut img_bo2 = hbm::Bo::with_layout(
        dev.clone(),
        &img_class,
        hbm::Extent::Image(img_width, img_height),
        img_layout,
        None,
    )
    .unwrap();
    img_bo2
        .bind_memory(MemoryType::MAPPABLE, Some(img_dmabuf))
        .unwrap();

    img_bo.map().unwrap();
    img_bo.flush();
    img_bo.invalidate();
    img_bo.unmap();

    let img_copy = hbm::CopyBufferImage {
        offset: 0,
        stride: (img_width * 4) as _,
        plane: 0,
        x: 0,
        y: 0,
        width: img_width,
        height: img_height,
    };

    let buf_desc = hbm::Description::new().flags(Flags::MAP | Flags::COPY);
    let buf_usage = Usage::Vulkan(hbm::vulkan::Usage::empty());
    let buf_class = dev.classify(buf_desc, slice::from_ref(&buf_usage)).unwrap();
    let buf_size = (img_width * img_height * 4) as u64;
    let mut buf_bo =
        hbm::Bo::with_constraint(dev.clone(), &buf_class, hbm::Extent::Buffer(buf_size), None)
            .unwrap();
    buf_bo.bind_memory(MemoryType::MAPPABLE, None).unwrap();

    buf_bo
        .copy_buffer_image(&img_bo, img_copy, None, true)
        .unwrap();
    img_bo
        .copy_buffer_image(&buf_bo, img_copy, None, true)
        .unwrap();
}

#[cfg(feature = "ash")]
fn test_buffer(dev: Arc<hbm::Device>) {
    let buf_desc = hbm::Description::new().flags(Flags::EXTERNAL | Flags::MAP | Flags::COPY);
    let buf_usage = Usage::Vulkan(hbm::vulkan::Usage::empty());
    let buf_class = dev.classify(buf_desc, slice::from_ref(&buf_usage)).unwrap();

    let buf_size = 13;
    let mut buf_bo =
        hbm::Bo::with_constraint(dev.clone(), &buf_class, hbm::Extent::Buffer(buf_size), None)
            .unwrap();
    buf_bo.bind_memory(MemoryType::MAPPABLE, None).unwrap();

    let buf_dmabuf = buf_bo.export_dma_buf(Some("buf")).unwrap();
    let buf_layout = buf_bo.layout();
    println!("buf size {} alloc {}", buf_size, buf_layout.size);

    let mut buf_bo2 = hbm::Bo::with_layout(
        dev.clone(),
        &buf_class,
        hbm::Extent::Buffer(buf_size),
        buf_layout,
        None,
    )
    .unwrap();
    buf_bo2
        .bind_memory(MemoryType::MAPPABLE, Some(buf_dmabuf))
        .unwrap();

    buf_bo.map().unwrap();
    buf_bo.flush();
    buf_bo.invalidate();
    buf_bo.unmap();

    let buf_copy = hbm::CopyBuffer {
        src_offset: 0,
        dst_offset: 0,
        size: buf_size,
    };
    let mut buf_src =
        hbm::Bo::with_constraint(dev.clone(), &buf_class, hbm::Extent::Buffer(buf_size), None)
            .unwrap();
    buf_src.bind_memory(MemoryType::MAPPABLE, None).unwrap();

    buf_bo.copy_buffer(&buf_src, buf_copy, None, true).unwrap();
}

#[cfg(feature = "ash")]
fn main() {
    env_logger::init();

    let backend = hbm::vulkan::Builder::new().build().unwrap();
    let dev = hbm::Builder::new().add_backend(backend).build().unwrap();

    test_buffer(dev.clone());
    test_image(dev.clone());
}

#[cfg(not(feature = "ash"))]
fn main() {
    println!("ash feature disabled");
}