From b7745aaa8b8f84cca70e80ac714c524cdc110877 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 23 Nov 2019 02:26:52 +0100 Subject: [PATCH] Make absolutely sure allocated frame memory is always 16-byte aligned --- src/rendering/swrenderer/r_memory.cpp | 40 +++++++++++++++++++++++++++ src/rendering/swrenderer/r_memory.h | 4 +-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/rendering/swrenderer/r_memory.cpp b/src/rendering/swrenderer/r_memory.cpp index 6e0556edb..dcc56f3bc 100644 --- a/src/rendering/swrenderer/r_memory.cpp +++ b/src/rendering/swrenderer/r_memory.cpp @@ -37,6 +37,7 @@ #include "po_man.h" #include "r_data/colormaps.h" #include "r_memory.h" +#include void *RenderMemory::AllocBytes(int size) { @@ -73,3 +74,42 @@ void RenderMemory::Clear() FreeBlocks.push_back(std::move(block)); } } + +static void* aligned_alloc(size_t alignment, size_t size) +{ + void* ptr; +#if defined _MSC_VER + ptr = _aligned_malloc(size, alignment); + if (!ptr) + throw std::bad_alloc(); +#else + // posix_memalign required alignment to be a min of sizeof(void *) + if (alignment < sizeof(void*)) + alignment = sizeof(void*); + + if (posix_memalign((void**)&ptr, alignment, size)) + throw std::bad_alloc(); +#endif + return ptr; +} + +static void aligned_free(void* ptr) +{ + if (ptr) + { +#if defined _MSC_VER + _aligned_free(ptr); +#else + free(ptr); +#endif + } +} + +RenderMemory::MemoryBlock::MemoryBlock() : Data(static_cast(aligned_alloc(16, BlockSize))), Position(0) +{ +} + +RenderMemory::MemoryBlock::~MemoryBlock() +{ + aligned_free(Data); +} diff --git a/src/rendering/swrenderer/r_memory.h b/src/rendering/swrenderer/r_memory.h index 67ade026e..8007b6cc1 100644 --- a/src/rendering/swrenderer/r_memory.h +++ b/src/rendering/swrenderer/r_memory.h @@ -29,8 +29,8 @@ private: struct MemoryBlock { - MemoryBlock() : Data(new uint8_t[BlockSize]), Position(0) { } - ~MemoryBlock() { delete[] Data; } + MemoryBlock(); + ~MemoryBlock(); MemoryBlock(const MemoryBlock &) = delete; MemoryBlock &operator=(const MemoryBlock &) = delete;