OpenGL: Implement UploadPool

This commit is contained in:
Lynix 2020-05-11 13:57:11 +02:00
parent eba0571f03
commit 6073d8f592
2 changed files with 46 additions and 11 deletions

View File

@ -35,10 +35,12 @@ namespace Nz
private: private:
struct Block struct Block
{ {
//< TODO std::vector<UInt8> memory;
UInt64 freeOffset; UInt64 freeOffset = 0;
}; };
std::vector<Block> m_blocks;
std::vector<Allocation> m_allocations;
UInt64 m_blockSize; UInt64 m_blockSize;
}; };
} }

View File

@ -11,23 +11,56 @@ namespace Nz
{ {
auto OpenGLUploadPool::Allocate(UInt64 size) -> Allocation& auto OpenGLUploadPool::Allocate(UInt64 size) -> Allocation&
{ {
/*const auto& deviceProperties = m_device.GetPhysicalDeviceInfo().properties; return Allocate(size, 1); //< Alignment doesn't matter
UInt64 preferredAlignement = deviceProperties.limits.optimalBufferCopyOffsetAlignment;*/
return Allocate(size, 0); //< FIXME
} }
auto OpenGLUploadPool::Allocate(UInt64 size, UInt64 alignment) -> Allocation& auto OpenGLUploadPool::Allocate(UInt64 size, UInt64 /*alignment*/) -> Allocation&
{ {
assert(size <= m_blockSize); assert(size <= m_blockSize);
static Allocation dummy; // Try to minimize lost space
return dummy; struct
{
Block* block = nullptr;
UInt64 offset = 0;
} bestBlock;
for (Block& block : m_blocks)
{
UInt64 alignedOffset = block.freeOffset;
if (block.freeOffset + size > m_blockSize)
continue; //< Not enough space
if (!bestBlock.block)
{
bestBlock.block = &block;
bestBlock.offset = block.freeOffset;
break; //< Since we have no alignment constraint, the first block is good
}
}
// No block found, allocate a new one
if (!bestBlock.block)
{
Block newBlock;
newBlock.memory.resize(m_blockSize);
bestBlock.block = &m_blocks.emplace_back(std::move(newBlock));
bestBlock.offset = 0;
}
Allocation& allocationData = m_allocations.emplace_back();
allocationData.mappedPtr = static_cast<UInt8*>(bestBlock.block->memory.data()) + bestBlock.offset;
allocationData.size = size;
return allocationData;
} }
void OpenGLUploadPool::Reset() void OpenGLUploadPool::Reset()
{ {
/*for (Block& block : m_blocks) for (Block& block : m_blocks)
block.freeOffset = 0;*/ block.freeOffset = 0;
m_allocations.clear();
} }
} }