rsx: Properly implement data alignment in simple_array<T>
This commit is contained in:
@@ -3,11 +3,46 @@
|
|||||||
#include <util/types.hpp>
|
#include <util/types.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "reverse_ptr.hpp"
|
#include "reverse_ptr.hpp"
|
||||||
|
|
||||||
namespace rsx
|
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>
|
template <typename C, typename T>
|
||||||
concept span_like =
|
concept span_like =
|
||||||
requires(C& c) {
|
requires(C& c) {
|
||||||
@@ -15,7 +50,7 @@ namespace rsx
|
|||||||
{ c.size() } -> std::integral;
|
{ 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>
|
requires std::is_trivially_destructible_v<Ty> && std::is_trivially_copyable_v<Ty>
|
||||||
struct simple_array
|
struct simple_array
|
||||||
{
|
{
|
||||||
@@ -28,7 +63,7 @@ namespace rsx
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr u32 _local_capacity = std::max<u32>(64u / sizeof(Ty), 1u);
|
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;
|
u32 _capacity = _local_capacity;
|
||||||
Ty* _data = _local_capacity ? reinterpret_cast<Ty*>(_local_storage) : nullptr;
|
Ty* _data = _local_capacity ? reinterpret_cast<Ty*>(_local_storage) : nullptr;
|
||||||
@@ -128,7 +163,7 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
if (!is_local_storage())
|
if (!is_local_storage())
|
||||||
{
|
{
|
||||||
free(_data);
|
aligned_allocator::free(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
_data = nullptr;
|
_data = nullptr;
|
||||||
@@ -196,13 +231,13 @@ namespace rsx
|
|||||||
if (is_local_storage())
|
if (is_local_storage())
|
||||||
{
|
{
|
||||||
// Switch to heap 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());
|
std::memcpy(static_cast<void*>(_data), _local_storage, size_bytes());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Extend heap storage
|
// 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;
|
_capacity = size;
|
||||||
|
|||||||
Reference in New Issue
Block a user