working on garbage collection, fixing small issues with font destroy

This commit is contained in:
2024-12-14 01:39:50 +01:00
parent f78c3e9f0f
commit 7bd2b9c4c7
9 changed files with 90 additions and 26 deletions

2
.gitignore vendored
View File

@@ -14,7 +14,7 @@
*.gch
*.pch
*.exe
*vgcore
*vgcore.*
*.gdb_history
.vs/
.xmake/

View File

@@ -11,7 +11,9 @@ namespace mlx
static void* Malloc(std::size_t size);
static void* AlignedMalloc(std::size_t alignment, std::size_t size);
static void* Calloc(std::size_t n, std::size_t size);
static void* AlignedCalloc(std::size_t alignment, std::size_t n, std::size_t size);
static void* Realloc(void* ptr, std::size_t size);
static void* AlignedRealloc(void* ptr, std::size_t alignment, std::size_t size);
static void Free(void* ptr);
inline static bool IsInit() noexcept { return s_instance != nullptr; }
@@ -19,9 +21,19 @@ namespace mlx
~MemManager();
private:
struct Descriptor
{
void* ptr;
std::size_t size;
bool aligned;
Descriptor(void* ptr, std::size_t size, bool aligned) : ptr(ptr), size(size), aligned(aligned) {}
};
private:
static MemManager* s_instance;
inline static std::vector<void*> s_blocks;
inline static std::vector<Descriptor> s_blocks;
};
}

View File

@@ -68,12 +68,15 @@
#endif
#include <Core/Memory.h>
#include <Core/Logs.h>
#define VMA_STATIC_VULKAN_FUNCTIONS 0
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0
#define VMA_VULKAN_VERSION 1000000
#define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) (mlx::MemManager::AlignedMalloc(alignment, size))
#define VMA_SYSTEM_ALIGNED_FREE(ptr) (mlx::MemManager::Free(ptr))
//#define VMA_ASSERT(expr) (mlx::Assert(expr, "VMA Assertion: " #expr))
#define VMA_ASSERT(expr) ((void)0)
#define VMA_ASSERT_LEAK(expr) ((void)0) // Because why not
#ifdef MLX_COMPILER_CLANG
@@ -104,7 +107,6 @@
#endif
#include <kvf.h>
#include <Core/Logs.h>
#include <Core/EventBus.h>
#include <Core/Profiler.h>
#include <Utils/NonOwningPtr.h>

View File

@@ -91,7 +91,6 @@ namespace mlx
if(gs)
gs->TryEraseSpritesInScene(texture);
}
m_image_registry.UnregisterTexture(texture);
delete texture;
}

View File

@@ -15,15 +15,24 @@ namespace mlx
{
void* ptr = std::malloc(size);
if(ptr != nullptr)
s_blocks.push_back(ptr);
s_blocks.emplace_back(ptr, size, false);
return ptr;
}
void* MemManager::AlignedMalloc(std::size_t alignment, std::size_t size)
{
void* ptr = std::aligned_alloc(alignment, size);
if(alignment < sizeof(void*))
alignment = sizeof(void*);
if(size % alignment != 0)
size += alignment - (size % alignment);
#ifdef MLX_COMPILER_MSVC
void* ptr = _aligned_malloc(alignment, size);
#else
void* ptr = std::aligned_alloc(alignment, size);
#endif
if(ptr != nullptr)
s_blocks.push_back(ptr);
s_blocks.emplace_back(ptr, size, true);
return ptr;
}
@@ -31,7 +40,14 @@ namespace mlx
{
void* ptr = std::calloc(n, size);
if(ptr != nullptr)
s_blocks.push_back(ptr);
s_blocks.emplace_back(ptr, n * size, false);
return ptr;
}
void* MemManager::AlignedCalloc(std::size_t alignment, std::size_t n, std::size_t size)
{
void* ptr = AlignedMalloc(alignment, n * size);
std::memset(ptr, 0, n * size);
return ptr;
}
@@ -39,33 +55,65 @@ namespace mlx
{
void* ptr2 = std::realloc(ptr, size);
if(ptr2 != nullptr)
s_blocks.push_back(ptr2);
auto it = std::find(s_blocks.begin(), s_blocks.end(), ptr);
s_blocks.emplace_back(ptr, size, false);
auto it = std::find_if(s_blocks.begin(), s_blocks.end(), [=](const Descriptor& rhs){ return ptr == rhs.ptr; });
if(it != s_blocks.end())
s_blocks.erase(it);
return ptr2;
}
void* MemManager::AlignedRealloc(void* ptr, std::size_t alignment, std::size_t size)
{
auto it = std::find_if(s_blocks.begin(), s_blocks.end(), [=](const Descriptor& rhs){ return ptr == rhs.ptr; });
#ifdef MLX_COMPILER_MSVC
void* ptr2 = _aligned_realloc(ptr, alignment, size);
#else
void* ptr2 = AlignedMalloc(alignment, size);
if(it != s_blocks.end())
std::memcpy(ptr2, ptr, it->size);
#endif
if(it != s_blocks.end())
s_blocks.erase(it);
if(ptr2 != nullptr)
s_blocks.emplace_back(ptr, size, true);
return ptr2;
}
void MemManager::Free(void* ptr)
{
if(ptr == nullptr)
return;
auto it = std::find(s_blocks.begin(), s_blocks.end(), ptr);
auto it = std::find_if(s_blocks.begin(), s_blocks.end(), [=](const Descriptor& rhs){ return ptr == rhs.ptr; });
if(it == s_blocks.end())
{
Error("Memory Manager: trying to free a pointer not allocated by the memory manager");
return;
}
std::free(*it);
#ifdef MLX_COMPILER_MSVC
if(it->aligned)
_aligned_free(it->ptr);
else
std::free(it->ptr);
#else
std::free(it->ptr);
#endif
s_blocks.erase(it);
}
MemManager::~MemManager()
{
std::for_each(s_blocks.begin(), s_blocks.end(), [](void* ptr)
for(const Descriptor& desc : s_blocks)
{
std::free(ptr);
});
#ifdef MLX_COMPILER_MSVC
if(it->aligned)
_aligned_free(desc.ptr);
else
std::free(desc.ptr);
#else
std::free(desc.ptr);
#endif
}
DebugLog("Memory Manager: finished garbage collection");
s_instance = nullptr;
}
}

View File

@@ -8,8 +8,8 @@
#include <stb_rect_pack.h>
#define STB_TRUETYPE_IMPLEMENTATION
#define STB_malloc(x, u) ((void)(u), mlx::MemManager::Get().Malloc(x))
#define STB_free(x, u) ((void)(u), mlx::MemManager::Get().Free(x))
#define STB_malloc(x, u) ((void)(u), mlx::MemManager::Malloc(x))
#define STB_free(x, u) ((void)(u), mlx::MemManager::Free(x))
#include <stb_truetype.h>
namespace mlx
@@ -64,6 +64,8 @@ namespace mlx
void Font::Destroy()
{
if(!m_atlas.IsInit())
return;
m_atlas.Destroy();
DebugLog("Font: unloaded % with a scale of %", m_name, m_scale);
}

View File

@@ -9,9 +9,9 @@
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ASSERT(x) (mlx::Assert(x, "internal stb assertion " #x))
#define STBI_MALLOC(x) (mlx::MemManager::Get().Malloc(x))
#define STBI_REALLOC(p, x) (mlx::MemManager::Get().Realloc(p, x))
#define STBI_FREE(x) (mlx::MemManager::Get().Free(x))
#define STBI_MALLOC(x) (mlx::MemManager::Malloc(x))
#define STBI_REALLOC(p, x) (mlx::MemManager::Realloc(p, x))
#define STBI_FREE(x) (mlx::MemManager::Free(x))
#ifdef MLX_COMPILER_GCC
#pragma GCC diagnostic push
@@ -295,7 +295,7 @@ namespace mlx
int channels;
std::uint8_t* data = stbi_load(filename.c_str(), &size.x, &size.y, &channels, 4);
CallOnExit defer([=]() { stbi_image_free(data); });
CallOnExit defer([&]() { stbi_image_free(data); });
CPUBuffer buffer(size.x * size.y * 4);
std::memcpy(buffer.GetData(), data, buffer.GetSize());

View File

@@ -59,9 +59,9 @@ namespace mlx
return MemManager::AlignedMalloc(alignment, size);
}
void* VulkanReallocationFunction(void*, void* ptr, std::size_t size, std::size_t, VkSystemAllocationScope)
void* VulkanReallocationFunction(void*, void* ptr, std::size_t size, std::size_t alignment, VkSystemAllocationScope)
{
return MemManager::Realloc(ptr, size);
return MemManager::AlignedRealloc(ptr, alignment, size);
}
void VulkanFreeFunction(void*, void* ptr)

View File

@@ -102,6 +102,7 @@ namespace mlx
VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice());
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence);
kvfDestroyFence(RenderCore::Get().GetDevice(), fence);
m_resize = false;
DebugLog("Vulkan: swapchain created");
}
}