mirror of
https://github.com/Kbz-8/42_vox.git
synced 2026-01-13 15:43:34 +00:00
improving allocator
This commit is contained in:
@@ -24,6 +24,7 @@ namespace Scop
|
||||
if(RenderCore::Get().vkMapMemory(m_device, m_memory, 0, VK_WHOLE_SIZE, 0, &p_map) != VK_SUCCESS)
|
||||
FatalError("Vulkan: failed to map a host visible chunk");
|
||||
}
|
||||
|
||||
MemoryBlock& block = m_blocks.emplace_back();
|
||||
block.memory = m_memory;
|
||||
block.offset = 0;
|
||||
@@ -37,7 +38,7 @@ namespace Scop
|
||||
{
|
||||
if(!m_blocks[i].free || m_blocks[i].size < size)
|
||||
continue;
|
||||
VkDeviceSize offset_displacement = (m_blocks[i].offset % alignment > 0) ? alignment - m_blocks[i].offset % alignment : 0;
|
||||
VkDeviceSize offset_displacement = (m_blocks[i].offset % alignment != 0) ? alignment - m_blocks[i].offset % alignment : 0;
|
||||
VkDeviceSize old_size_available = m_blocks[i].size - offset_displacement;
|
||||
|
||||
if(size + offset_displacement <= m_blocks[i].size)
|
||||
@@ -51,7 +52,7 @@ namespace Scop
|
||||
|
||||
MemoryBlock new_block;
|
||||
new_block.memory = m_memory;
|
||||
new_block.offset = m_blocks[i].offset + size;
|
||||
new_block.offset = m_blocks[i].offset + m_blocks[i].size;
|
||||
new_block.size = old_size_available - size;
|
||||
new_block.free = true;
|
||||
|
||||
@@ -76,9 +77,9 @@ namespace Scop
|
||||
end = true;
|
||||
for(auto it = m_blocks.begin(); it != m_blocks.end(); ++it)
|
||||
{
|
||||
if(it->free && (it + 1)->free)
|
||||
if(it->free && it + 1 != m_blocks.end() && (it + 1)->free)
|
||||
{
|
||||
it->size = (it + 1)->offset + (it + 1)->size - it->offset;
|
||||
it->size += (it + 1)->size;
|
||||
m_blocks.erase(it + 1);
|
||||
end = false;
|
||||
break;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <Renderer/Memory/DeviceAllocator.h>
|
||||
#include <Renderer/RenderCore.h>
|
||||
#include <Maths/Constants.h>
|
||||
#include <Core/Logs.h>
|
||||
|
||||
@@ -6,7 +7,15 @@
|
||||
|
||||
namespace Scop
|
||||
{
|
||||
constexpr VkDeviceSize CHUNK_SIZE = MaxValue<std::uint16_t>();
|
||||
#define AlignUp(val, alignment) (val + alignment - 1) & ~(alignment - 1)
|
||||
|
||||
void DeviceAllocator::AttachToDevice(VkDevice device, VkPhysicalDevice physical) noexcept
|
||||
{
|
||||
m_device = device;
|
||||
m_physical = physical;
|
||||
|
||||
RenderCore::Get().vkGetPhysicalDeviceMemoryProperties(physical, &m_mem_props);
|
||||
}
|
||||
|
||||
[[nodiscard]] MemoryBlock DeviceAllocator::Allocate(VkDeviceSize size, VkDeviceSize alignment, std::int32_t memory_type_index, bool dedicated_chunk)
|
||||
{
|
||||
@@ -25,7 +34,8 @@ namespace Scop
|
||||
}
|
||||
}
|
||||
}
|
||||
m_chunks.emplace_back(std::make_unique<MemoryChunk>(m_device, m_physical, (CHUNK_SIZE < size + alignment ? size + alignment : CHUNK_SIZE), memory_type_index, dedicated_chunk));
|
||||
VkDeviceSize chunk_size = CalcPreferredChunkSize(memory_type_index);
|
||||
m_chunks.emplace_back(std::make_unique<MemoryChunk>(m_device, m_physical, chunk_size, memory_type_index, dedicated_chunk));
|
||||
std::optional<MemoryBlock> block = m_chunks.back()->Allocate(size, alignment);
|
||||
m_allocations_count++;
|
||||
if(block.has_value())
|
||||
@@ -54,4 +64,12 @@ namespace Scop
|
||||
}
|
||||
Error("Device Allocator: unable to free a block; could not find it's chunk");
|
||||
}
|
||||
|
||||
VkDeviceSize DeviceAllocator::CalcPreferredChunkSize(std::uint32_t mem_type_index)
|
||||
{
|
||||
std::uint32_t heap_index = m_mem_props.memoryTypes[mem_type_index].heapIndex;
|
||||
VkDeviceSize heap_size = m_mem_props.memoryHeaps[heap_index].size;
|
||||
bool is_small_heap = heap_size <= SMALL_HEAP_MAX_SIZE;
|
||||
return AlignUp((is_small_heap ? (heap_size / 8) : DEFAULT_LARGE_HEAP_BLOCK_SIZE), (VkDeviceSize)32);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user