diff --git a/rpcs3/Emu/RSX/Common/bitfield.hpp b/rpcs3/Emu/RSX/Common/bitfield.hpp new file mode 100644 index 0000000000..ee67d415e8 --- /dev/null +++ b/rpcs3/Emu/RSX/Common/bitfield.hpp @@ -0,0 +1,93 @@ +#pragma once + +#include +#include + +namespace rsx +{ + template + void unpack_bitset(const std::bitset& block, u64* values) + { + for (int bit = 0, n = -1, shift = 0; bit < N; ++bit, ++shift) + { + if ((bit % 64) == 0) + { + values[++n] = 0; + shift = 0; + } + + if (block[bit]) + { + values[n] |= (1ull << shift); + } + } + } + + template + void pack_bitset(std::bitset& block, u64* values) + { + for (int n = 0, shift = 0; shift < N; ++n, shift += 64) + { + std::bitset tmp = values[n]; + tmp <<= shift; + block |= tmp; + } + } + + template + class atomic_bitmask_t + { + private: + atomic_t m_data{ 0 }; + + public: + atomic_bitmask_t() = default; + + T load() const + { + return static_cast(m_data.load()); + } + + void store(T value) + { + m_data.store(static_cast(value)); + } + + bool operator & (T mask) const + { + return ((m_data.load() & static_cast(mask)) != 0); + } + + T operator | (T mask) const + { + return static_cast(m_data.load() | static_cast(mask)); + } + + void operator &= (T mask) + { + m_data.fetch_and(static_cast(mask)); + } + + void operator |= (T mask) + { + m_data.fetch_or(static_cast(mask)); + } + + bool test_and_set(T mask) + { + const auto old = m_data.fetch_or(static_cast(mask)); + return (old & static_cast(mask)) != 0; + } + + auto clear(T mask) + { + bitmask_type clear_mask = ~(static_cast(mask)); + return m_data.and_fetch(clear_mask); + } + + void clear() + { + m_data.store(0); + } + }; +} diff --git a/rpcs3/Emu/RSX/Common/profiling_timer.hpp b/rpcs3/Emu/RSX/Common/profiling_timer.hpp new file mode 100644 index 0000000000..a31843b536 --- /dev/null +++ b/rpcs3/Emu/RSX/Common/profiling_timer.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include + +namespace rsx +{ + struct profiling_timer + { + bool enabled = false; + steady_clock::time_point last; + + profiling_timer() = default; + + void start() + { + if (enabled) [[unlikely]] + { + last = steady_clock::now(); + } + } + + s64 duration() + { + if (!enabled) [[likely]] + { + return 0ll; + } + + auto old = last; + last = steady_clock::now(); + return std::chrono::duration_cast(last - old).count(); + } + }; +} diff --git a/rpcs3/Emu/RSX/Common/simple_array.hpp b/rpcs3/Emu/RSX/Common/simple_array.hpp new file mode 100644 index 0000000000..e39b7be264 --- /dev/null +++ b/rpcs3/Emu/RSX/Common/simple_array.hpp @@ -0,0 +1,278 @@ +#pragma once + +#include + +namespace rsx +{ + template + struct simple_array + { + public: + using iterator = Ty*; + using const_iterator = const Ty*; + using value_type = Ty; + + private: + u32 _capacity = 0; + u32 _size = 0; + Ty* _data = nullptr; + + inline u64 offset(const_iterator pos) + { + return (_data) ? u64(pos - _data) : 0ull; + } + + public: + simple_array() = default; + + simple_array(u32 initial_size, const Ty val = {}) + { + reserve(initial_size); + _size = initial_size; + + for (u32 n = 0; n < initial_size; ++n) + { + _data[n] = val; + } + } + + simple_array(const std::initializer_list& args) + { + reserve(::size32(args)); + + for (const auto& arg : args) + { + push_back(arg); + } + } + + simple_array(const simple_array& other) + { + _capacity = other._capacity; + _size = other._size; + + const auto size_bytes = sizeof(Ty) * _capacity; + _data = static_cast(malloc(size_bytes)); + std::memcpy(_data, other._data, size_bytes); + } + + simple_array(simple_array&& other) noexcept + { + swap(other); + } + + simple_array& operator=(const simple_array& other) + { + if (&other != this) + { + simple_array{ other }.swap(*this); + } + + return *this; + } + + simple_array& operator=(simple_array&& other) noexcept + { + swap(other); + return *this; + } + + ~simple_array() + { + if (_data) + { + free(_data); + _data = nullptr; + _size = _capacity = 0; + } + } + + void swap(simple_array& other) noexcept + { + std::swap(_capacity, other._capacity); + std::swap(_size, other._size); + std::swap(_data, other._data); + } + + void reserve(u32 size) + { + if (_capacity >= size) + return; + + ensure(_data = static_cast(std::realloc(_data, sizeof(Ty) * size))); // "realloc() failed!" + _capacity = size; + } + + void resize(u32 size) + { + reserve(size); + _size = size; + } + + void push_back(const Ty& val) + { + if (_size >= _capacity) + { + reserve(_capacity + 16); + } + + _data[_size++] = val; + } + + void push_back(Ty&& val) + { + if (_size >= _capacity) + { + reserve(_capacity + 16); + } + + _data[_size++] = val; + } + + Ty pop_back() + { + return _data[--_size]; + } + + iterator insert(iterator pos, const Ty& val) + { + ensure(pos >= _data); + const auto _loc = offset(pos); + + if (_size >= _capacity) + { + reserve(_capacity + 16); + pos = _data + _loc; + } + + if (_loc >= _size) + { + _data[_size++] = val; + return pos; + } + + ensure(_loc < _size); + + const auto remaining = (_size - _loc); + memmove(pos + 1, pos, remaining * sizeof(Ty)); + + *pos = val; + _size++; + + return pos; + } + + iterator insert(iterator pos, Ty&& val) + { + ensure(pos >= _data); + const auto _loc = offset(pos); + + if (_size >= _capacity) + { + reserve(_capacity + 16); + pos = _data + _loc; + } + + if (_loc >= _size) + { + _data[_size++] = val; + return pos; + } + + ensure(_loc < _size); + + const u32 remaining = (_size - _loc); + memmove(pos + 1, pos, remaining * sizeof(Ty)); + + *pos = val; + _size++; + + return pos; + } + + void clear() + { + _size = 0; + } + + bool empty() const + { + return _size == 0; + } + + u32 size() const + { + return _size; + } + + u64 size_bytes() const + { + return _size * sizeof(Ty); + } + + u32 capacity() const + { + return _capacity; + } + + Ty& operator[] (u32 index) + { + return _data[index]; + } + + const Ty& operator[] (u32 index) const + { + return _data[index]; + } + + Ty* data() + { + return _data; + } + + const Ty* data() const + { + return _data; + } + + Ty& back() + { + return _data[_size - 1]; + } + + const Ty& back() const + { + return _data[_size - 1]; + } + + Ty& front() + { + return _data[0]; + } + + const Ty& front() const + { + return _data[0]; + } + + iterator begin() + { + return _data; + } + + iterator end() + { + return _data ? _data + _size : nullptr; + } + + const_iterator begin() const + { + return _data; + } + + const_iterator end() const + { + return _data ? _data + _size : nullptr; + } + }; +} diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 574d713bfc..38dc655125 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -1,9 +1,9 @@ #pragma once #include "util/types.hpp" +#include "../Common/simple_array.hpp" #include "../Overlays/overlays.h" #include "GLTexture.h" -#include "Emu/RSX/rsx_utils.h" #include #include diff --git a/rpcs3/Emu/RSX/RSXOffload.cpp b/rpcs3/Emu/RSX/RSXOffload.cpp index ed911aa9c3..666f1883ad 100644 --- a/rpcs3/Emu/RSX/RSXOffload.cpp +++ b/rpcs3/Emu/RSX/RSXOffload.cpp @@ -3,7 +3,6 @@ #include "Common/BufferUtils.h" #include "RSXOffload.h" #include "RSXThread.h" -#include "rsx_utils.h" #include #include "util/asm.hpp" diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index a2ed1913f6..05b8290f07 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -9,7 +9,6 @@ #include "Common/surface_store.h" #include "Capture/rsx_capture.h" #include "rsx_methods.h" -#include "rsx_utils.h" #include "gcm_printing.h" #include "Emu/Cell/lv2/sys_event.h" #include "Emu/Cell/lv2/sys_time.h" diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 2d0262f038..a39530afb0 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -12,6 +12,8 @@ #include "RSXFIFO.h" #include "RSXOffload.h" #include "rsx_utils.h" +#include "Common/bitfield.hpp" +#include "Common/profiling_timer.hpp" #include "Common/texture_cache_types.h" #include "Program/RSXVertexProgram.h" #include "Program/RSXFragmentProgram.h" diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index b165f8af70..6a39549925 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -1,6 +1,8 @@ #pragma once +#include "../Common/simple_array.hpp" #include "../Overlays/overlay_controls.h" + #include "VKProgramPipeline.h" #include "VKHelpers.h" diff --git a/rpcs3/Emu/RSX/rsx_cache.h b/rpcs3/Emu/RSX/rsx_cache.h index 4aa2c24bd3..15b3066742 100644 --- a/rpcs3/Emu/RSX/rsx_cache.h +++ b/rpcs3/Emu/RSX/rsx_cache.h @@ -2,13 +2,13 @@ #include "Utilities/File.h" #include "Utilities/lockless.h" #include "Utilities/Thread.h" -#include "Program/ProgramStateCache.h" +#include "Common/bitfield.hpp" #include "Emu/System.h" #include "Emu/cache_utils.hpp" +#include "Program/ProgramStateCache.h" #include "Common/texture_cache_checker.h" #include "Overlays/Shaders/shader_loading_dialog.h" -#include "rsx_utils.h" #include #include diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index 16a2c02f81..1b8a922ae7 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -6,7 +6,7 @@ #include "rsx_decode.h" #include "RSXTexture.h" #include "rsx_vertex_data.h" -#include "rsx_utils.h" +#include "Common/simple_array.hpp" #include "Emu/Cell/timers.hpp" #include "Program/program_util.h" diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index df0c0e03be..caa8f29b0b 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -851,380 +851,4 @@ namespace rsx return base * scale; } - - template - void unpack_bitset(const std::bitset& block, u64* values) - { - for (int bit = 0, n = -1, shift = 0; bit < N; ++bit, ++shift) - { - if ((bit % 64) == 0) - { - values[++n] = 0; - shift = 0; - } - - if (block[bit]) - { - values[n] |= (1ull << shift); - } - } - } - - template - void pack_bitset(std::bitset& block, u64* values) - { - for (int n = 0, shift = 0; shift < N; ++n, shift += 64) - { - std::bitset tmp = values[n]; - tmp <<= shift; - block |= tmp; - } - } - - template - class atomic_bitmask_t - { - private: - atomic_t m_data{0}; - - public: - atomic_bitmask_t() = default; - - T load() const - { - return static_cast(m_data.load()); - } - - void store(T value) - { - m_data.store(static_cast(value)); - } - - bool operator & (T mask) const - { - return ((m_data.load() & static_cast(mask)) != 0); - } - - T operator | (T mask) const - { - return static_cast(m_data.load() | static_cast(mask)); - } - - void operator &= (T mask) - { - m_data.fetch_and(static_cast(mask)); - } - - void operator |= (T mask) - { - m_data.fetch_or(static_cast(mask)); - } - - bool test_and_set(T mask) - { - const auto old = m_data.fetch_or(static_cast(mask)); - return (old & static_cast(mask)) != 0; - } - - auto clear(T mask) - { - bitmask_type clear_mask = ~(static_cast(mask)); - return m_data.and_fetch(clear_mask); - } - - void clear() - { - m_data.store(0); - } - }; - - template - struct simple_array - { - public: - using iterator = Ty*; - using const_iterator = const Ty*; - using value_type = Ty; - - private: - u32 _capacity = 0; - u32 _size = 0; - Ty* _data = nullptr; - - inline u64 offset(const_iterator pos) - { - return (_data) ? u64(pos - _data) : 0ull; - } - - public: - simple_array() = default; - - simple_array(u32 initial_size, const Ty val = {}) - { - reserve(initial_size); - _size = initial_size; - - for (u32 n = 0; n < initial_size; ++n) - { - _data[n] = val; - } - } - - simple_array(const std::initializer_list& args) - { - reserve(::size32(args)); - - for (const auto& arg : args) - { - push_back(arg); - } - } - - simple_array(const simple_array& other) - { - _capacity = other._capacity; - _size = other._size; - - const auto size_bytes = sizeof(Ty) * _capacity; - _data = static_cast(malloc(size_bytes)); - std::memcpy(_data, other._data, size_bytes); - } - - simple_array(simple_array&& other) noexcept - { - swap(other); - } - - simple_array& operator=(const simple_array& other) - { - if (&other != this) - { - simple_array{other}.swap(*this); - } - - return *this; - } - - simple_array& operator=(simple_array&& other) noexcept - { - swap(other); - return *this; - } - - ~simple_array() - { - if (_data) - { - free(_data); - _data = nullptr; - _size = _capacity = 0; - } - } - - void swap(simple_array& other) noexcept - { - std::swap(_capacity, other._capacity); - std::swap(_size, other._size); - std::swap(_data, other._data); - } - - void reserve(u32 size) - { - if (_capacity >= size) - return; - - ensure(_data = static_cast(std::realloc(_data, sizeof(Ty) * size))); // "realloc() failed!" - _capacity = size; - } - - void resize(u32 size) - { - reserve(size); - _size = size; - } - - void push_back(const Ty& val) - { - if (_size >= _capacity) - { - reserve(_capacity + 16); - } - - _data[_size++] = val; - } - - void push_back(Ty&& val) - { - if (_size >= _capacity) - { - reserve(_capacity + 16); - } - - _data[_size++] = val; - } - - iterator insert(iterator pos, const Ty& val) - { - ensure(pos >= _data); - const auto _loc = offset(pos); - - if (_size >= _capacity) - { - reserve(_capacity + 16); - pos = _data + _loc; - } - - if (_loc >= _size) - { - _data[_size++] = val; - return pos; - } - - ensure(_loc < _size); - - const auto remaining = (_size - _loc); - memmove(pos + 1, pos, remaining * sizeof(Ty)); - - *pos = val; - _size++; - - return pos; - } - - iterator insert(iterator pos, Ty&& val) - { - ensure(pos >= _data); - const auto _loc = offset(pos); - - if (_size >= _capacity) - { - reserve(_capacity + 16); - pos = _data + _loc; - } - - if (_loc >= _size) - { - _data[_size++] = val; - return pos; - } - - ensure(_loc < _size); - - const u32 remaining = (_size - _loc); - memmove(pos + 1, pos, remaining * sizeof(Ty)); - - *pos = val; - _size++; - - return pos; - } - - void clear() - { - _size = 0; - } - - bool empty() const - { - return _size == 0; - } - - u32 size() const - { - return _size; - } - - u32 capacity() const - { - return _capacity; - } - - Ty& operator[] (u32 index) - { - return _data[index]; - } - - const Ty& operator[] (u32 index) const - { - return _data[index]; - } - - Ty* data() - { - return _data; - } - - const Ty* data() const - { - return _data; - } - - Ty& back() - { - return _data[_size - 1]; - } - - const Ty& back() const - { - return _data[_size - 1]; - } - - Ty& front() - { - return _data[0]; - } - - const Ty& front() const - { - return _data[0]; - } - - iterator begin() - { - return _data; - } - - iterator end() - { - return _data ? _data + _size : nullptr; - } - - const_iterator begin() const - { - return _data; - } - - const_iterator end() const - { - return _data ? _data + _size : nullptr; - } - }; - - struct profiling_timer - { - bool enabled = false; - steady_clock::time_point last; - - profiling_timer() = default; - - void start() - { - if (enabled) [[unlikely]] - { - last = steady_clock::now(); - } - } - - s64 duration() - { - if (!enabled) [[likely]] - { - return 0ll; - } - - auto old = last; - last = steady_clock::now(); - return std::chrono::duration_cast(last - old).count(); - } - }; } diff --git a/rpcs3/Emu/RSX/rsx_vertex_data.h b/rpcs3/Emu/RSX/rsx_vertex_data.h index 7e9e59197c..2f38c995b4 100644 --- a/rpcs3/Emu/RSX/rsx_vertex_data.h +++ b/rpcs3/Emu/RSX/rsx_vertex_data.h @@ -2,8 +2,8 @@ #include "gcm_enums.h" +#include "Common/simple_array.hpp" #include "util/types.hpp" -#include "rsx_utils.h" namespace rsx { diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 79e0cf0599..85d789f9d4 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -458,12 +458,15 @@ - - - - - - + + + + + + + + + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 061552307f..c0394c45b3 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1990,6 +1990,15 @@ Emu + + Emu\GPU\RSX\Common + + + Emu\GPU\RSX\Common + + + Emu\GPU\RSX\Common +