CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/GPU/Vulkan/VulkanMemory.h
Views: 1401
#pragma once12#include <cstdint>3#include <cstring>4#include <functional>5#include <vector>67#include "Common/Data/Collections/FastVec.h"8#include "Common/GPU/Vulkan/VulkanContext.h"9#include "Common/GPU/GPUBackendCommon.h"1011// Forward declaration12VK_DEFINE_HANDLE(VmaAllocation);1314// VulkanMemory15//16// Vulkan memory management utils.1718// Simple memory pushbuffer pool that can share blocks between the "frames", to reduce the impact of push memory spikes -19// a later frame can gobble up redundant buffers from an earlier frame even if they don't share frame index.20// NOT thread safe! Can only be used from one thread (our main thread).21class VulkanPushPool : public GPUMemoryManager {22public:23VulkanPushPool(VulkanContext *vulkan, const char *name, size_t originalBlockSize, VkBufferUsageFlags usage);24~VulkanPushPool();2526void Destroy();27void BeginFrame();2829const char *Name() const override {30return name_;31}32void GetDebugString(char *buffer, size_t bufSize) const override;3334// When using the returned memory, make sure to bind the returned vkbuf.35// It is okay to allocate 0 bytes.36uint8_t *Allocate(VkDeviceSize numBytes, VkDeviceSize alignment, VkBuffer *vkbuf, uint32_t *bindOffset) {37_dbg_assert_(curBlockIndex_ >= 0);3839Block &block = blocks_[curBlockIndex_];4041VkDeviceSize offset = (block.used + (alignment - 1)) & ~(alignment - 1);42if (offset + numBytes <= block.size) {43block.used = offset + numBytes;44*vkbuf = block.buffer;45*bindOffset = (uint32_t)offset;46return block.writePtr + offset;47}4849NextBlock(numBytes);5051*vkbuf = blocks_[curBlockIndex_].buffer;52*bindOffset = 0; // Newly allocated buffer will start at 0.53return blocks_[curBlockIndex_].writePtr;54}5556// NOTE: If you can avoid this by writing the data directly into memory returned from Allocate,57// do so. Savings from avoiding memcpy can be significant.58VkDeviceSize Push(const void *data, VkDeviceSize numBytes, int alignment, VkBuffer *vkbuf) {59uint32_t bindOffset;60uint8_t *ptr = Allocate(numBytes, alignment, vkbuf, &bindOffset);61memcpy(ptr, data, numBytes);62return bindOffset;63}6465size_t GetUsedThisFrame() const;6667private:68void NextBlock(VkDeviceSize allocationSize);6970struct Block {71~Block();72VkBuffer buffer;73VmaAllocation allocation;7475VkDeviceSize size;76VkDeviceSize used;7778int frameIndex;79bool original; // these blocks aren't garbage collected.80double lastUsed;8182uint8_t *writePtr;8384void Destroy(VulkanContext *vulkan);85};8687Block CreateBlock(size_t sz);8889VulkanContext *vulkan_;90VkDeviceSize originalBlockSize_;91std::vector<Block> blocks_;92VkBufferUsageFlags usage_;93int curBlockIndex_ = -1;94const char *name_;95};969798