mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-04-18 15:31:35 -06:00
rsx: Improve handling of aligned memory
This commit is contained in:
parent
8121bd443c
commit
1b1143094e
88
rpcs3/Emu/RSX/Common/aligned_malloc.hpp
Normal file
88
rpcs3/Emu/RSX/Common/aligned_malloc.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
namespace aligned_allocator
|
||||
{
|
||||
template <size_t Align>
|
||||
requires (Align != 0) && ((Align& (Align - 1)) == 0)
|
||||
size_t align_up(size_t size)
|
||||
{
|
||||
return (size + (Align - 1)) & ~(Align - 1);
|
||||
}
|
||||
|
||||
template <size_t Align>
|
||||
requires (Align != 0) && ((Align& (Align - 1)) == 0)
|
||||
void* malloc(size_t size)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return _aligned_malloc(size, Align);
|
||||
#elif defined(__APPLE__)
|
||||
constexpr size_t NativeAlign = std::max(Align, sizeof(void*));
|
||||
return std::aligned_alloc(NativeAlign, align_up<NativeAlign>(size));
|
||||
#else
|
||||
return std::aligned_alloc(Align, align_up<Align>(size));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <size_t Align>
|
||||
requires (Align != 0) && ((Align& (Align - 1)) == 0)
|
||||
void* realloc(void* prev_ptr, [[maybe_unused]] size_t prev_size, size_t new_size)
|
||||
{
|
||||
if (align_up<Align>(prev_size) >= new_size)
|
||||
{
|
||||
return prev_ptr;
|
||||
}
|
||||
|
||||
ensure(reinterpret_cast<usz>(prev_ptr) % Align == 0, "Pointer not aligned to Align");
|
||||
#if defined(_WIN32)
|
||||
return _aligned_realloc(prev_ptr, new_size, Align);
|
||||
#else
|
||||
#if defined(__APPLE__)
|
||||
constexpr size_t NativeAlign = std::max(Align, sizeof(void*));
|
||||
void* ret = std::aligned_alloc(NativeAlign, align_up<NativeAlign>(new_size));
|
||||
#else
|
||||
void* ret = std::aligned_alloc(Align, align_up<Align>(new_size));
|
||||
#endif
|
||||
std::memcpy(ret, prev_ptr, std::min(prev_size, new_size));
|
||||
std::free(prev_ptr);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void free(void* ptr)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
std::free(ptr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, int Alignment = sizeof(T)>
|
||||
class aligned_pointer_t
|
||||
{
|
||||
public:
|
||||
aligned_pointer_t(size_t size)
|
||||
{
|
||||
m_ptr = aligned_allocator::malloc<Alignment>(size);
|
||||
}
|
||||
|
||||
virtual ~aligned_pointer_t()
|
||||
{
|
||||
aligned_allocator::free(m_ptr);
|
||||
}
|
||||
|
||||
T* data() const { return m_ptr; }
|
||||
|
||||
T& operator * () const { return *m_ptr; }
|
||||
|
||||
T* operator -> () const { return m_ptr; }
|
||||
|
||||
private:
|
||||
T* m_ptr;
|
||||
};
|
||||
}
|
||||
@ -81,10 +81,17 @@ namespace rsx
|
||||
std::span<T> as_span() const
|
||||
{
|
||||
auto bytes = data();
|
||||
ensure((reinterpret_cast<uintptr_t>(bytes) & (sizeof(T) - 1)) == 0, "IO buffer span cast requires naturally aligned pointers.");
|
||||
ensure(is_naturally_aligned<T>(), "IO buffer span cast requires naturally aligned pointers.");
|
||||
return { utils::bless<T>(bytes), m_size / sizeof(T) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool is_naturally_aligned() const
|
||||
{
|
||||
return ((reinterpret_cast<uintptr_t>(data()) & (alignof(T) - 1)) == 0) &&
|
||||
(m_size % sizeof(T)) == 0;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return m_size == 0;
|
||||
|
||||
@ -3,70 +3,12 @@
|
||||
#include <util/types.hpp>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "aligned_malloc.hpp"
|
||||
#include "reverse_ptr.hpp"
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
namespace aligned_allocator
|
||||
{
|
||||
template <size_t Align>
|
||||
requires (Align != 0) && ((Align & (Align - 1)) == 0)
|
||||
size_t align_up(size_t size)
|
||||
{
|
||||
return (size + (Align - 1)) & ~(Align - 1);
|
||||
}
|
||||
|
||||
template <size_t Align>
|
||||
requires (Align != 0) && ((Align & (Align - 1)) == 0)
|
||||
void* malloc(size_t size)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return _aligned_malloc(size, Align);
|
||||
#elif defined(__APPLE__)
|
||||
constexpr size_t NativeAlign = std::max(Align, sizeof(void*));
|
||||
return std::aligned_alloc(NativeAlign, align_up<NativeAlign>(size));
|
||||
#else
|
||||
return std::aligned_alloc(Align, align_up<Align>(size));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <size_t Align>
|
||||
requires (Align != 0) && ((Align & (Align - 1)) == 0)
|
||||
void* realloc(void* prev_ptr, [[maybe_unused]] size_t prev_size, size_t new_size)
|
||||
{
|
||||
if (align_up<Align>(prev_size) >= new_size)
|
||||
{
|
||||
return prev_ptr;
|
||||
}
|
||||
|
||||
ensure(reinterpret_cast<usz>(prev_ptr) % Align == 0, "Pointer not aligned to Align");
|
||||
#if defined(_WIN32)
|
||||
return _aligned_realloc(prev_ptr, new_size, Align);
|
||||
#else
|
||||
#if defined(__APPLE__)
|
||||
constexpr size_t NativeAlign = std::max(Align, sizeof(void*));
|
||||
void* ret = std::aligned_alloc(NativeAlign, align_up<NativeAlign>(new_size));
|
||||
#else
|
||||
void* ret = std::aligned_alloc(Align, align_up<Align>(new_size));
|
||||
#endif
|
||||
std::memcpy(ret, prev_ptr, std::min(prev_size, new_size));
|
||||
std::free(prev_ptr);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void free(void* ptr)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
std::free(ptr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template <typename C, typename T>
|
||||
concept span_like =
|
||||
requires(C& c) {
|
||||
|
||||
@ -661,6 +661,7 @@
|
||||
<ClInclude Include="Emu\NP\ip_address.h" />
|
||||
<ClInclude Include="Emu\perf_monitor.hpp" />
|
||||
<ClInclude Include="Emu\RSX\color_utils.h" />
|
||||
<ClInclude Include="Emu\RSX\Common\aligned_malloc.hpp" />
|
||||
<ClInclude Include="Emu\RSX\Common\bitfield.hpp" />
|
||||
<ClInclude Include="Emu\RSX\Common\buffer_stream.hpp" />
|
||||
<ClInclude Include="Emu\RSX\Common\reverse_ptr.hpp" />
|
||||
|
||||
@ -2872,6 +2872,9 @@
|
||||
<ClInclude Include="Emu\RSX\Overlays\overlay_arrow.h">
|
||||
<Filter>Emu\GPU\RSX\Overlays</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\Common\aligned_malloc.hpp">
|
||||
<Filter>Emu\GPU\RSX\Common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user