mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-01-05 00:00:56 +01:00
rsx: Properly implement data alignment in simple_array<T>
This commit is contained in:
parent
7f6842705c
commit
6e11978638
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue