Program Listing for File VulkanBuffer.cpp#
↰ Return to documentation for file (Src/GraphicsEngineVulkan/vulkan_base/VulkanBuffer.cpp)
module;
#include <cstdint>
#include <utility>
#include <vulkan/vulkan.hpp>
#include "common/MemoryHelper.hpp"
#include "common/Utilities.hpp"
#include "spdlog/spdlog.h"
module kataglyphis.vulkan.buffer;
import kataglyphis.vulkan.device;
Kataglyphis::VulkanBuffer::VulkanBuffer() = default;
Kataglyphis::VulkanBuffer::VulkanBuffer(VulkanBuffer &&other) noexcept
: device(other.device), buffer(other.buffer), bufferMemory(other.bufferMemory), created(other.created)
{
other.device = nullptr;
other.buffer = vk::Buffer{};
other.bufferMemory = vk::DeviceMemory{};
other.created = false;
}
auto Kataglyphis::VulkanBuffer::operator=(VulkanBuffer &&other) noexcept -> VulkanBuffer &
{
if (this != &other) {
cleanUp();
device = other.device;
buffer = other.buffer;
bufferMemory = other.bufferMemory;
created = other.created;
other.device = nullptr;
other.buffer = vk::Buffer{};
other.bufferMemory = vk::DeviceMemory{};
other.created = false;
}
return *this;
}
void Kataglyphis::VulkanBuffer::create(VulkanDevice *vulkan_device,
vk::DeviceSize buffer_size,
vk::BufferUsageFlags buffer_usage_flags,
vk::MemoryPropertyFlags buffer_propertiy_flags,
vk::MemoryAllocateFlags buffer_allocate_flags)
{
device = vulkan_device;
// information to create a buffer (doesn't include assigning memory)
vk::BufferCreateInfo buffer_info{};
buffer_info.size = buffer_size;
// multiple types of buffer possible, e.g. vertex buffer
buffer_info.usage = buffer_usage_flags;
// similar to swap chain images, can share vertex buffers
buffer_info.sharingMode = vk::SharingMode::eExclusive;
buffer = device->getLogicalDevice().createBuffer(buffer_info).value;
// get buffer memory requirements
vk::MemoryRequirements memory_requirements = device->getLogicalDevice().getBufferMemoryRequirements(buffer);
// allocate memory to buffer
vk::MemoryAllocateInfo memory_alloc_info{};
memory_alloc_info.allocationSize = memory_requirements.size;
memory_alloc_info.pNext = nullptr;
vk::MemoryAllocateFlagsInfo memory_allocate_flags_info{};
if (buffer_allocate_flags) {
memory_allocate_flags_info.flags = buffer_allocate_flags;
memory_alloc_info.pNext = &memory_allocate_flags_info;
}
uint32_t const memory_type_index = Kataglyphis::find_memory_type_index(
device->getPhysicalDevice(), memory_requirements.memoryTypeBits, buffer_propertiy_flags);
// VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | /* memory is visible to
// CPU side
// */ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT /* data is placed straight into
// buffer */);
if (memory_type_index < 0) { spdlog::error("Failed to find suitable memory type!"); }
memory_alloc_info.memoryTypeIndex = memory_type_index;
// allocate memory to VkDeviceMemory
bufferMemory = device->getLogicalDevice().allocateMemory(memory_alloc_info).value;
// allocate memory to given buffer
std::ignore = device->getLogicalDevice().bindBufferMemory(buffer, bufferMemory, 0);
created = true;
}
void Kataglyphis::VulkanBuffer::cleanUp()
{
if (created && device != nullptr) {
device->getLogicalDevice().destroyBuffer(buffer);
device->getLogicalDevice().freeMemory(bufferMemory);
}
buffer = vk::Buffer{};
bufferMemory = vk::DeviceMemory{};
created = false;
}
Kataglyphis::VulkanBuffer::~VulkanBuffer() = default;