diff --git a/rpcs3/Emu/RSX/Common/aligned_malloc.hpp b/rpcs3/Emu/RSX/Common/aligned_malloc.hpp new file mode 100644 index 0000000000..2ca59c3cf2 --- /dev/null +++ b/rpcs3/Emu/RSX/Common/aligned_malloc.hpp @@ -0,0 +1,88 @@ +#pragma once + +#include + +namespace rsx +{ + namespace aligned_allocator + { + template + requires (Align != 0) && ((Align& (Align - 1)) == 0) + size_t align_up(size_t size) + { + return (size + (Align - 1)) & ~(Align - 1); + } + + template + 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(size)); +#else + return std::aligned_alloc(Align, align_up(size)); +#endif + } + + template + 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(prev_size) >= new_size) + { + return prev_ptr; + } + + ensure(reinterpret_cast(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(new_size)); +#else + void* ret = std::aligned_alloc(Align, align_up(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 + class aligned_pointer_t + { + public: + aligned_pointer_t(size_t size) + { + m_ptr = aligned_allocator::malloc(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; + }; +} diff --git a/rpcs3/Emu/RSX/Common/io_buffer.h b/rpcs3/Emu/RSX/Common/io_buffer.h index 59e8e6a32e..edca80675b 100644 --- a/rpcs3/Emu/RSX/Common/io_buffer.h +++ b/rpcs3/Emu/RSX/Common/io_buffer.h @@ -81,10 +81,17 @@ namespace rsx std::span as_span() const { auto bytes = data(); - ensure((reinterpret_cast(bytes) & (sizeof(T) - 1)) == 0, "IO buffer span cast requires naturally aligned pointers."); + ensure(is_naturally_aligned(), "IO buffer span cast requires naturally aligned pointers."); return { utils::bless(bytes), m_size / sizeof(T) }; } + template + bool is_naturally_aligned() const + { + return ((reinterpret_cast(data()) & (alignof(T) - 1)) == 0) && + (m_size % sizeof(T)) == 0; + } + bool empty() const { return m_size == 0; diff --git a/rpcs3/Emu/RSX/Common/simple_array.hpp b/rpcs3/Emu/RSX/Common/simple_array.hpp index 6852e670fb..a37df9dd54 100644 --- a/rpcs3/Emu/RSX/Common/simple_array.hpp +++ b/rpcs3/Emu/RSX/Common/simple_array.hpp @@ -3,70 +3,12 @@ #include #include #include -#include +#include "aligned_malloc.hpp" #include "reverse_ptr.hpp" namespace rsx { - namespace aligned_allocator - { - template - requires (Align != 0) && ((Align & (Align - 1)) == 0) - size_t align_up(size_t size) - { - return (size + (Align - 1)) & ~(Align - 1); - } - - template - 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(size)); -#else - return std::aligned_alloc(Align, align_up(size)); -#endif - } - - template - 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(prev_size) >= new_size) - { - return prev_ptr; - } - - ensure(reinterpret_cast(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(new_size)); -#else - void* ret = std::aligned_alloc(Align, align_up(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 concept span_like = requires(C& c) { diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 7253171856..42aab47a04 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -661,6 +661,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index a5a5825f44..6b9c82c959 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -2872,6 +2872,9 @@ Emu\GPU\RSX\Overlays + + Emu\GPU\RSX\Common +