Files
OpenVulkano/openVulkanoCpp/Vulkan/Buffer.hpp
2023-10-03 19:52:23 +02:00

110 lines
3.3 KiB
C++

#pragma once
#include "Base/ICloseable.hpp"
#include "Device.hpp"
namespace OpenVulkano
{
namespace Vulkan
{
/**
* \brief A not managed buffer. This should be used rarely.
*/
struct Buffer : public ICloseable
{
vk::Device device;
vk::DeviceMemory memory;
vk::DeviceSize size = 0, alignment = 0, allocSize = 0;
vk::MemoryPropertyFlags memoryPropertyFlags;
void* mapped = nullptr;
/**
* \brief Maps the buffer into the memory of the host.
* \tparam T The type of the buffers data.
* \param offset The offset from where to map the buffer.
* \param size The size to be mapped. VK_WHOLE_SIZE to map the whole buffer.
* \return The pointer to the mapped buffer.
*/
template <typename T = void>
T * Map(size_t offset = 0, VkDeviceSize size = VK_WHOLE_SIZE)
{
mapped = device.mapMemory(memory, offset, size, vk::MemoryMapFlags());
return static_cast<T*>(mapped);
}
/**
* \brief Un-maps the buffer from the host.
*/
void UnMap()
{
device.unmapMemory(memory);
mapped = nullptr;
}
/**
* \brief Copies data into the mapped buffer. Will not do anything if the buffer is not mapped!
* \param size The size of the data to copy.
* \param data The data to copy
* \param offset The offset for where to copy the data to in the buffer.
*/
void Copy(size_t size, const void* data, VkDeviceSize offset = 0) const
{
if (!mapped) return;
memcpy(static_cast<uint8_t*>(mapped) + offset, data, size);
}
/**
* \brief Copies data into the mapped buffer. Will not do anything if the buffer is not mapped!
* \param data The data to copy.
* \param offset The offset for where to copy the data to in the buffer.
*/
template <typename T>
void Copy(const T& data, VkDeviceSize offset = 0) const
{
Copy(sizeof(T), &data, offset);
}
/**
* \brief Copies data into the mapped buffer. Will not do anything if the buffer is not mapped!
* \param data The data to copy.
* \param offset The offset for where to copy the data to in the buffer.
*/
template <typename T>
void Copy(const std::vector<T>& data, VkDeviceSize offset = 0) const
{
copy(sizeof(T) * data.size(), data.data(), offset);
}
/**
* \brief Flushes the memory region of the buffer to the device. This should be only necessary for non coherent memory.
* \param size The amount to flush. VK_WHOLE_SIZE flushes the entire buffer.
* \param offset The offset from where to start the flush.
*/
void Flush(vk::DeviceSize size = VK_WHOLE_SIZE, vk::DeviceSize offset = 0) const
{
device.flushMappedMemoryRanges(vk::MappedMemoryRange(memory, offset, size));
}
/**
* \brief Invalidates the memory region of the buffer to allow access from the host. This should be only necessary for non coherent memory.
* \param size The amount to make available. VK_WHOLE_SIZE invalidate the entire buffer.
* \param offset The offset from where to make the memory available.
*/
void Invalidate(vk::DeviceSize size = VK_WHOLE_SIZE, vk::DeviceSize offset = 0) const
{
device.invalidateMappedMemoryRanges(vk::MappedMemoryRange(memory, offset, size));
}
void Close() override
{
if (mapped) UnMap();
if(memory)
{
device.free(memory);
memory = vk::DeviceMemory();
}
}
};
}
}