Renderer: Allow UploadPool to handle very big (>= 2MB) blocks
This commit is contained in:
parent
131d5f7afb
commit
51c099b3ce
|
|
@ -42,6 +42,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
std::vector<UInt8> memory;
|
std::vector<UInt8> memory;
|
||||||
UInt64 freeOffset = 0;
|
UInt64 freeOffset = 0;
|
||||||
|
UInt64 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::size_t m_nextAllocationIndex;
|
std::size_t m_nextAllocationIndex;
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ namespace Nz
|
||||||
Vk::DeviceMemory blockMemory;
|
Vk::DeviceMemory blockMemory;
|
||||||
Vk::Buffer buffer;
|
Vk::Buffer buffer;
|
||||||
UInt64 freeOffset = 0;
|
UInt64 freeOffset = 0;
|
||||||
|
UInt64 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
UInt64 m_blockSize;
|
UInt64 m_blockSize;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ namespace Nz
|
||||||
|
|
||||||
for (Block& block : m_blocks)
|
for (Block& block : m_blocks)
|
||||||
{
|
{
|
||||||
if (block.freeOffset + size > m_blockSize)
|
if (block.freeOffset + size > block.size)
|
||||||
continue; //< Not enough space
|
continue; //< Not enough space
|
||||||
|
|
||||||
if (!bestBlock.block)
|
if (!bestBlock.block)
|
||||||
|
|
@ -41,7 +41,12 @@ namespace Nz
|
||||||
// No block found, allocate a new one
|
// No block found, allocate a new one
|
||||||
if (!bestBlock.block)
|
if (!bestBlock.block)
|
||||||
{
|
{
|
||||||
|
// Handle really big allocations (TODO: Handle them separately as they shouldn't be common and can consume a lot of memory)
|
||||||
|
UInt64 blockSize = std::max(m_blockSize, size);
|
||||||
|
|
||||||
Block newBlock;
|
Block newBlock;
|
||||||
|
newBlock.size = blockSize;
|
||||||
|
|
||||||
newBlock.memory.resize(m_blockSize);
|
newBlock.memory.resize(m_blockSize);
|
||||||
|
|
||||||
bestBlock.block = &m_blocks.emplace_back(std::move(newBlock));
|
bestBlock.block = &m_blocks.emplace_back(std::move(newBlock));
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@ namespace Nz
|
||||||
|
|
||||||
auto VulkanUploadPool::Allocate(UInt64 size, UInt64 alignment) -> VulkanAllocation&
|
auto VulkanUploadPool::Allocate(UInt64 size, UInt64 alignment) -> VulkanAllocation&
|
||||||
{
|
{
|
||||||
assert(size <= m_blockSize);
|
|
||||||
|
|
||||||
// Try to minimize lost space
|
// Try to minimize lost space
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
@ -32,7 +30,7 @@ namespace Nz
|
||||||
for (Block& block : m_blocks)
|
for (Block& block : m_blocks)
|
||||||
{
|
{
|
||||||
UInt64 alignedOffset = AlignPow2(block.freeOffset, alignment);
|
UInt64 alignedOffset = AlignPow2(block.freeOffset, alignment);
|
||||||
if (alignedOffset + size > m_blockSize)
|
if (alignedOffset + size > block.size)
|
||||||
continue; //< Not enough space
|
continue; //< Not enough space
|
||||||
|
|
||||||
UInt64 lostSpace = alignedOffset - block.freeOffset;
|
UInt64 lostSpace = alignedOffset - block.freeOffset;
|
||||||
|
|
@ -48,8 +46,13 @@ namespace Nz
|
||||||
// No block found, allocate a new one
|
// No block found, allocate a new one
|
||||||
if (!bestBlock.block)
|
if (!bestBlock.block)
|
||||||
{
|
{
|
||||||
|
// Handle really big allocations (TODO: Handle them separately as they shouldn't be common and can consume a lot of memory)
|
||||||
|
UInt64 blockSize = std::max(m_blockSize, size);
|
||||||
|
|
||||||
Block newBlock;
|
Block newBlock;
|
||||||
if (!newBlock.buffer.Create(m_device, 0U, m_blockSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT))
|
newBlock.size = blockSize;
|
||||||
|
|
||||||
|
if (!newBlock.buffer.Create(m_device, 0U, blockSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT))
|
||||||
throw std::runtime_error("failed to create block buffer: " + TranslateVulkanError(newBlock.buffer.GetLastErrorCode()));
|
throw std::runtime_error("failed to create block buffer: " + TranslateVulkanError(newBlock.buffer.GetLastErrorCode()));
|
||||||
|
|
||||||
VkMemoryRequirements requirement = newBlock.buffer.GetMemoryRequirements();
|
VkMemoryRequirements requirement = newBlock.buffer.GetMemoryRequirements();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue