-
Tobias Frisch authored
Signed-off-by:
Tobias Frisch <tfrisch@uni-koblenz.de>
Tobias Frisch authoredSigned-off-by:
Tobias Frisch <tfrisch@uni-koblenz.de>
Buffer.hpp 5.39 KiB
#pragma once
/**
* @authors Tobias Frisch, Lars Hoerttrich, Alexander Gauggel
* @file vkcv/Buffer.hpp
* @brief Template buffer class for type security with buffers.
*/
#include "BufferTypes.hpp"
#include "Container.hpp"
#include "Core.hpp"
#include "Handles.hpp"
namespace vkcv {
/**
* @brief Template class for buffer handling and filling data.
*
* @tparam T Buffer content type
*/
template <typename T>
class Buffer {
public:
Buffer() : m_core(nullptr), m_handle() {}
Buffer(Core* core, const BufferHandle &handle) : m_core(core), m_handle(handle) {}
Buffer(const Buffer &other) = default;
Buffer(Buffer &&other) noexcept = default;
~Buffer() = default;
Buffer &operator=(const Buffer &other) = default;
Buffer &operator=(Buffer &&other) noexcept = default;
/**
* @brief Returns the buffers handle.
*
* @return The #BufferHandle to be used with the #Core
*/
[[nodiscard]] const BufferHandle &getHandle() const {
return m_handle;
}
/**
* @brief Returns the type of the buffer.
*
* @return The #BufferType of the #Buffer
*/
[[nodiscard]] BufferType getType() const {
return m_core->getBufferType(m_handle);
};
[[nodiscard]] BufferMemoryType getMemoryType() const {
return m_core->getBufferMemoryType(m_handle);
}
/**
* @brief Returns the stride of elements in the buffer.
*
* Beware that this returned value is only the correct
* stride for this buffer if it is used tightly packed
* storing elements of type T.
*
* @return The likely stride of the #Buffer using type T
*/
[[nodiscard]] size_t getStride() const {
return sizeof(T);
}
/**
* @brief Returns the count of elements in the buffer.
*
* @return The number of objects of type T the #Buffer holds
*/
[[nodiscard]] size_t getCount() const {
return m_core->getBufferSize(m_handle) / sizeof(T);
}
/**
* @brief Returns the size of the buffer in bytes.
*
* @return The size of the #Buffer in bytes
*/
[[nodiscard]] size_t getSize() const {
return m_core->getBufferSize(m_handle);
}
/**
* @brief Returns the vulkan buffer handle of the buffer.
*
* @return The vulkan handle of the #Buffer to be used for manual vulkan commands
*/
[[nodiscard]] vk::Buffer getVulkanHandle() const {
return m_core->getBuffer(m_handle);
}
/**
* @brief Fills the #Buffer with data of type T.
*
* @param[in] data Pointer to the array of object type T
* @param[in] count The number of objects to copy from the data array
* @param[in] offset The offset into the #Buffer where the data is copied into
*/
void fill(const T* data, size_t count = 0, size_t offset = 0) {
m_core->fillBuffer(m_handle, data, count * sizeof(T), offset * sizeof(T));
}
/**
* @brief Fills the #Buffer with data from a vector of type T.
*
* @param vector Vector of type T to be copied into the #Buffer
* @param offset The offset into the #Buffer where the data is copied into
*/
void fill(const Vector<T> &vector, size_t offset = 0) {
fill(static_cast<const T*>(vector.data()), static_cast<size_t>(vector.size()), offset);
}
/**
* @brief Fills the #Buffer with data from an array of type T
* and size N.
*
* @tparam N Size of the array to be copied into the #Buffer
* @param array Array of type T to be copied into the #Buffer
* @param offset The offset into the #Buffer where the data is copied into
*/
template<size_t N>
void fill(const std::array<T, N> &array, size_t offset = 0) {
fill(static_cast<const T*>(array.data()), N, offset);
}
/**
* @brief Reads the #Buffer directly into a data pointer of type T.
*
* @param[in] data Pointer to the array of object type T
* @param[in] count The number of objects to copy from the buffer
* @param[in] offset The offset into the #Buffer where the data is copied from
*/
void read(T* data, size_t count = 0, size_t offset = 0) {
m_core->readBuffer(m_handle, data, count * sizeof(T), offset * sizeof(T));
}
/**
* @brief Reads the #Buffer directly to a vector of type T.
*
* @param vector Vector of type T to be copied into from the #Buffer
* @param offset The offset into the #Buffer where the data is copied from
*/
void read(Vector<T> &vector, size_t offset = 0) {
read(static_cast<T*>(vector.data()), static_cast<size_t>(vector.size()), offset);
}
/**
* @brief Maps memory to the #Buffer and returns it.
*
* @param[in] offset Offset of mapping in objects of type T
* @param[in] count Count of objects of type T that are mapped
* @return Pointer to mapped memory as type T
*/
[[nodiscard]] T* map(size_t offset = 0, size_t count = 0) {
return reinterpret_cast<T*>(
m_core->mapBuffer(m_handle, offset * sizeof(T), count * sizeof(T)));
}
/**
* @brief Unmaps the #Buffer, invalidates the pointer obtained by map().
*/
void unmap() {
m_core->unmapBuffer(m_handle);
}
private:
Core* m_core;
BufferHandle m_handle;
};
template <typename T>
Buffer<T> buffer(Core &core, BufferType type, size_t count,
BufferMemoryType memoryType = BufferMemoryType::DEVICE_LOCAL,
bool readable = false) {
return Buffer<T>(&core,
core.createBuffer(type, typeGuard<T>(), count, memoryType, readable));
}
template <typename T>
VertexBufferBinding vertexBufferBinding(const Buffer<T>& buffer) {
return vertexBufferBinding(buffer.getHandle(), buffer.getStride());
}
} // namespace vkcv