2022-12-11 17:06:28 +11:00
|
|
|
use crate::{error, util};
|
2022-12-22 13:39:31 +11:00
|
|
|
use ash::vk;
|
|
|
|
use std::ffi::c_void;
|
2023-01-15 07:06:43 +11:00
|
|
|
use std::sync::Arc;
|
2022-12-11 17:06:28 +11:00
|
|
|
|
|
|
|
pub struct VulkanImageMemory {
|
|
|
|
pub handle: vk::DeviceMemory,
|
2023-01-15 07:06:43 +11:00
|
|
|
device: Arc<ash::Device>,
|
2022-12-11 17:06:28 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
impl VulkanImageMemory {
|
2022-12-22 13:39:31 +11:00
|
|
|
pub fn new(
|
2023-01-15 07:06:43 +11:00
|
|
|
device: &Arc<ash::Device>,
|
2022-12-22 13:39:31 +11:00
|
|
|
alloc: &vk::MemoryAllocateInfo,
|
|
|
|
) -> error::Result<VulkanImageMemory> {
|
2022-12-11 17:06:28 +11:00
|
|
|
unsafe {
|
|
|
|
Ok(VulkanImageMemory {
|
|
|
|
handle: device.allocate_memory(alloc, None)?,
|
2022-12-22 13:39:31 +11:00
|
|
|
device: device.clone(),
|
2022-12-11 17:06:28 +11:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-22 13:39:31 +11:00
|
|
|
pub fn bind(&self, image: &vk::Image) -> error::Result<()> {
|
2022-12-11 17:06:28 +11:00
|
|
|
unsafe {
|
2022-12-22 13:39:31 +11:00
|
|
|
Ok(self
|
|
|
|
.device
|
2023-01-16 03:08:13 +11:00
|
|
|
.bind_image_memory(*image, self.handle, 0)?)
|
2022-12-11 17:06:28 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for VulkanImageMemory {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
self.device.free_memory(self.handle, None);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct VulkanBuffer {
|
|
|
|
pub handle: vk::Buffer,
|
|
|
|
device: ash::Device,
|
|
|
|
pub memory: vk::DeviceMemory,
|
|
|
|
pub size: vk::DeviceSize,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct VulkanBufferMapHandle<'a> {
|
|
|
|
buffer: &'a mut VulkanBuffer,
|
2022-12-22 13:39:31 +11:00
|
|
|
ptr: *mut c_void,
|
2022-12-11 17:06:28 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
impl VulkanBuffer {
|
2022-12-22 13:39:31 +11:00
|
|
|
pub fn new(
|
|
|
|
device: &ash::Device,
|
|
|
|
mem_props: &vk::PhysicalDeviceMemoryProperties,
|
|
|
|
usage: vk::BufferUsageFlags,
|
|
|
|
size: usize,
|
|
|
|
) -> error::Result<VulkanBuffer> {
|
2022-12-11 17:06:28 +11:00
|
|
|
unsafe {
|
|
|
|
let buffer_info = vk::BufferCreateInfo::builder()
|
|
|
|
.size(size as vk::DeviceSize)
|
|
|
|
.usage(usage)
|
|
|
|
.sharing_mode(vk::SharingMode::EXCLUSIVE)
|
|
|
|
.build();
|
|
|
|
let buffer = device.create_buffer(&buffer_info, None)?;
|
|
|
|
|
|
|
|
let memory_reqs = device.get_buffer_memory_requirements(buffer);
|
|
|
|
let alloc_info = vk::MemoryAllocateInfo::builder()
|
|
|
|
.allocation_size(memory_reqs.size)
|
2022-12-22 13:39:31 +11:00
|
|
|
.memory_type_index(util::find_vulkan_memory_type(
|
|
|
|
mem_props,
|
|
|
|
memory_reqs.memory_type_bits,
|
|
|
|
vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT,
|
2023-01-14 08:10:54 +11:00
|
|
|
)?)
|
2022-12-11 17:06:28 +11:00
|
|
|
.build();
|
|
|
|
|
|
|
|
let alloc = device.allocate_memory(&alloc_info, None)?;
|
2023-01-16 03:08:13 +11:00
|
|
|
device.bind_buffer_memory(buffer, alloc, 0)?;
|
2022-12-11 17:06:28 +11:00
|
|
|
|
|
|
|
Ok(VulkanBuffer {
|
|
|
|
handle: buffer,
|
|
|
|
memory: alloc,
|
|
|
|
size: size as vk::DeviceSize,
|
2022-12-22 13:39:31 +11:00
|
|
|
device: device.clone(),
|
2022-12-11 17:06:28 +11:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn map(&mut self) -> error::Result<VulkanBufferMapHandle> {
|
2022-12-22 13:39:31 +11:00
|
|
|
let dst = unsafe {
|
|
|
|
self.device
|
|
|
|
.map_memory(self.memory, 0, self.size, vk::MemoryMapFlags::empty())?
|
|
|
|
};
|
2022-12-11 17:06:28 +11:00
|
|
|
|
|
|
|
Ok(VulkanBufferMapHandle {
|
|
|
|
buffer: self,
|
|
|
|
ptr: dst,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for VulkanBuffer {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
if self.memory != vk::DeviceMemory::null() {
|
|
|
|
self.device.free_memory(self.memory, None);
|
|
|
|
}
|
|
|
|
|
|
|
|
if self.handle != vk::Buffer::null() {
|
|
|
|
self.device.destroy_buffer(self.handle, None);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-22 13:39:31 +11:00
|
|
|
impl<'a> VulkanBufferMapHandle<'a> {
|
2022-12-25 17:18:11 +11:00
|
|
|
pub unsafe fn copy_from(&mut self, offset: usize, src: &[u8]) {
|
2023-01-10 14:54:54 +11:00
|
|
|
std::ptr::copy_nonoverlapping(
|
|
|
|
src.as_ptr(),
|
|
|
|
self.ptr
|
|
|
|
.map_addr(|original| original.wrapping_add(offset))
|
|
|
|
.cast(),
|
|
|
|
src.len(),
|
|
|
|
);
|
2022-12-11 17:06:28 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-22 13:39:31 +11:00
|
|
|
impl<'a> Drop for VulkanBufferMapHandle<'a> {
|
2022-12-11 17:06:28 +11:00
|
|
|
fn drop(&mut self) {
|
2022-12-22 13:39:31 +11:00
|
|
|
unsafe { self.buffer.device.unmap_memory(self.buffer.memory) }
|
2022-12-11 17:06:28 +11:00
|
|
|
}
|
2022-12-22 13:39:31 +11:00
|
|
|
}
|