rotex-vulkan 0.1.0

A Vulkan backend for rotex_core
Documentation
use ash::vk;

use super::device::Device;
use crate::core::Instance;
use crate::error::{Error, ErrorKind};

pub struct RotexBuffer {
    handle: vk::Buffer,
    device_memory: vk::DeviceMemory,
    size: vk::DeviceSize,
}

impl RotexBuffer {
    pub fn new(
        instance: &Instance,
        device: &Device,
        size: vk::DeviceSize,
        usage: vk::BufferUsageFlags,
        properties: vk::MemoryPropertyFlags,
    ) -> Result<Self, Error> {
        let buffer_info = vk::BufferCreateInfo::default()
            .size(size)
            .usage(usage)
            .sharing_mode(vk::SharingMode::EXCLUSIVE);

        let handle = unsafe { device.logical_device().create_buffer(&buffer_info, None) }
            .map_err(ErrorKind::Vulkan)
            .map_err(Error::fatal)?;

        let requirements = unsafe { device.logical_device().get_buffer_memory_requirements(handle) };
        let memory_type =
            device.find_memory_type(instance, requirements.memory_type_bits, properties)?;

        let alloc_info = vk::MemoryAllocateInfo::default()
            .allocation_size(requirements.size)
            .memory_type_index(memory_type);

        let device_memory = unsafe { device.logical_device().allocate_memory(&alloc_info, None) }
            .map_err(ErrorKind::Vulkan)
            .map_err(Error::fatal)?;

        unsafe {
            device
                .logical_device()
                .bind_buffer_memory(handle, device_memory, 0)
        }
        .map_err(ErrorKind::Vulkan)
        .map_err(Error::fatal)?;

        Ok(Self {
            handle,
            device_memory,
            size,
        })
    }

    pub fn map(&self, device: &Device) -> Result<*mut std::ffi::c_void, Error> {
        unsafe {
            device.logical_device().map_memory(
                self.device_memory,
                0,
                self.size,
                vk::MemoryMapFlags::empty(),
            )
        }
        .map_err(ErrorKind::Vulkan)
        .map_err(Error::fatal)
    }

    pub fn unmap(&self, device: &Device) {
        unsafe { device.logical_device().unmap_memory(self.device_memory) };
    }

    pub fn handle(&self) -> vk::Buffer {
        self.handle
    }

    pub fn size(&self) -> vk::DeviceSize {
        self.size
    }

    pub fn destroy(&self, device: &Device) {
        unsafe {
            device.logical_device().destroy_buffer(self.handle, None);
            device
                .logical_device()
                .free_memory(self.device_memory, None);
        }
    }
}