librashader/librashader-runtime-vk/src/vulkan_primitives.rs

142 lines
3.9 KiB
Rust
Raw Normal View History

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;
2022-12-11 17:06:28 +11:00
pub struct VulkanImageMemory {
pub handle: vk::DeviceMemory,
2022-12-22 13:39:31 +11:00
device: ash::Device,
2022-12-11 17:06:28 +11:00
}
impl VulkanImageMemory {
2022-12-22 13:39:31 +11:00
pub fn new(
device: &ash::Device,
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
.bind_image_memory(image.clone(), self.handle.clone(), 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,
))
2022-12-11 17:06:28 +11:00
.build();
let alloc = device.allocate_memory(&alloc_info, None)?;
device.bind_buffer_memory(buffer.clone(), alloc.clone(), 0)?;
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 unsafe fn copy_from(&mut self, buffer: &[u8]) -> error::Result<()> {
2022-12-22 13:39:31 +11:00
let dst = self
.device
.map_memory(self.memory, 0, self.size, vk::MemoryMapFlags::empty())?;
2022-12-11 17:06:28 +11:00
std::ptr::copy_nonoverlapping(buffer.as_ptr(), dst.cast(), buffer.len());
self.device.unmap_memory(self.memory);
Ok(())
}
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
}