#ifndef _VULKAN_BUFFER_H #define _VULKAN_BUFFER_H /* * This class is intended to be used with Storage Buffers and Uniform Buffers. */ template class VulkanBuffer { public: // TODO: Make these private (maybe make a getter for numObjects) // Externally, they are only used in resizeBufferSet size_t capacity; // temp field to help with ubo+ssbo resizing until they are added to this class // See if I need a separate field for this or if I can use other fields to check for this // Maybe compare uniform or storage buffer size to the size of the memory allocated here bool resized; VulkanBuffer(); VulkanBuffer(size_t capacity, size_t minOffsetAlignment); VulkanBuffer(const VulkanBuffer&) = delete; VulkanBuffer(VulkanBuffer&& other); ~VulkanBuffer(); VulkanBuffer& operator=(const VulkanBuffer&) = delete; VulkanBuffer& operator=(VulkanBuffer&& other) noexcept; void resize(); void add(T obj); // TODO: Add a resize function private: size_t alignment; size_t numObjects; T* srcData; // TODO: Rename this to something else probably and rename rawData to data vector* vData; // Remember that this is a pointer to the mapped video memory // Maybe rename it to mappedData or something to make that clearer void* rawData; }; // Currently, for SSBOs, I store the per-object values (usually just the model matrix), on each object, so they // are not in their own array and therefore cannot be pushed to the GPU as one block. The updates must happen // separately per object. // Since Sascha WIllems' dynamic UBO example works the same way (iirc), I can implement dynamic UBOs like that as well // for now. Would be nice to plan for potentially storing the ubo data on the CPU in a contiguous block in the future, // assuming that would make updates easier. Keep in mind that this only makes sense if all or most of the objects // in the ubo get updated every frame. // ============================= TODO: Also, check when it makes sense to have a staging buffer for copying data to the GPU // and see if I actually need to use it everywhere I currently am. I think this is mentioned in Sascha WIllems dubo example // or some other Vulkan website I recently bookmarked template VulkanBuffer::VulkanBuffer() : alignment(0) , capacity(0) , numObjects(0) , resized(false) , srcData(nullptr) , rawData(nullptr) , vData(nullptr) { } template VulkanBuffer::VulkanBuffer(size_t capacity, size_t minOffsetAlignment) : alignment(sizeof(T)) , capacity(capacity) , numObjects(0) , resized(false) , srcData(nullptr) , rawData(nullptr) , vData(nullptr) { if (minOffsetAlignment > 0) { alignment = (alignment + minOffsetAlignment - 1) & ~(minOffsetAlignment - 1); } srcData = (T*)malloc(capacity * alignment); } template VulkanBuffer::VulkanBuffer(VulkanBuffer&& other) { // TODO: Implement } template VulkanBuffer::~VulkanBuffer() { if (srcData != nullptr) { free(srcData); } } template VulkanBuffer& VulkanBuffer::operator=(VulkanBuffer&& other) noexcept { if (this != &other) { capacity = other.capacity; numObjects = other.numObjects; resized = other.resized; alignment = other.alignment; if (srcData != nullptr) { free(srcData); } srcData = other.srcData; other.capacity = 0; other.numObjects = 0; // TODO: Maybe set rnage to 0 as well other.srcData = nullptr; } return *this; } template void VulkanBuffer::resize() { resized = false; } template void VulkanBuffer::add(T obj) { if (numObjects == capacity) { // Once I add Vulkan buffer objects in here, make sure this doesn't overlap with resizeBufferSet resized = true; capacity *= 2; } numObjects++; } #endif // _VULKAN_BUFFER_H