rsx: Properly implement data alignment in simple_array<T>

This commit is contained in:
kd-11 2025-11-21 02:07:06 +03:00 committed by Elad
parent 7f6842705c
commit 6e11978638

View file

@ -3,11 +3,46 @@
#include <util/types.hpp>
#include <functional>
#include <algorithm>
#include <cstdlib>
#include "reverse_ptr.hpp"
namespace rsx
{
namespace aligned_allocator
{
template <size_t Align>
void* malloc(size_t size)
{
#ifdef _MSC_VER
return _aligned_malloc(size, Align);
#else
return std::aligned_alloc(Align, size);
#endif
}
template <size_t Align>
void* realloc(void* prev_ptr, [[maybe_unused]] size_t prev_size, size_t new_size)
{
#ifdef _MSC_VER
return _aligned_realloc(prev_ptr, new_size, Align);
#else
void* ret = std::aligned_alloc(Align, new_size);
std::memcpy(ret, prev_ptr, std::min(prev_size, new_size));
return ret;
#endif
}
static inline void free(void* ptr)
{
#ifdef _MSC_VER
_aligned_free(ptr);
#else
std::free(ptr);
#endif
}
}
template <typename C, typename T>
concept span_like =
requires(C& c) {
@ -15,7 +50,7 @@ namespace rsx
{ c.size() } -> std::integral;
};
template <typename Ty>
template <typename Ty, size_t Align=alignof(Ty)>
requires std::is_trivially_destructible_v<Ty> && std::is_trivially_copyable_v<Ty>
struct simple_array
{
@ -28,7 +63,7 @@ namespace rsx
private:
static constexpr u32 _local_capacity = std::max<u32>(64u / sizeof(Ty), 1u);
char _local_storage[_local_capacity * sizeof(Ty)];
alignas(Align) char _local_storage[_local_capacity * sizeof(Ty)];
u32 _capacity = _local_capacity;
Ty* _data = _local_capacity ? reinterpret_cast<Ty*>(_local_storage) : nullptr;
@ -128,7 +163,7 @@ namespace rsx
{
if (!is_local_storage())
{
free(_data);
aligned_allocator::free(_data);
}
_data = nullptr;
@ -196,13 +231,13 @@ namespace rsx
if (is_local_storage())
{
// Switch to heap storage
ensure(_data = static_cast<Ty*>(std::malloc(sizeof(Ty) * size)));
ensure(_data = static_cast<Ty*>(aligned_allocator::malloc<Align>(sizeof(Ty) * size)));
std::memcpy(static_cast<void*>(_data), _local_storage, size_bytes());
}
else
{
// Extend heap storage
ensure(_data = static_cast<Ty*>(std::realloc(_data, sizeof(Ty) * size))); // "realloc() failed!"
ensure(_data = static_cast<Ty*>(aligned_allocator::realloc<Align>(_data, size_bytes(), sizeof(Ty) * size))); // "realloc() failed!"
}
_capacity = size;