diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp index d59fd13300..296b9976c7 100644 --- a/Source/Core/Common/Arm64Emitter.cpp +++ b/Source/Core/Common/Arm64Emitter.cpp @@ -18,6 +18,7 @@ #include "Common/BitUtils.h" #include "Common/CommonTypes.h" #include "Common/MathUtil.h" +#include "Common/SmallVector.h" #ifdef _WIN32 #include @@ -1794,33 +1795,6 @@ void ARM64XEmitter::ADRP(ARM64Reg Rd, s64 imm) EncodeAddressInst(1, Rd, static_cast(imm >> 12)); } -template -class SmallVector final -{ -public: - SmallVector() = default; - explicit SmallVector(size_t size) : m_size(size) {} - - void push_back(const T& x) { m_array[m_size++] = x; } - void push_back(T&& x) { m_array[m_size++] = std::move(x); } - - template - T& emplace_back(Args&&... args) - { - return m_array[m_size++] = T{std::forward(args)...}; - } - - T& operator[](size_t i) { return m_array[i]; } - const T& operator[](size_t i) const { return m_array[i]; } - - size_t size() const { return m_size; } - bool empty() const { return m_size == 0; } - -private: - std::array m_array{}; - size_t m_size = 0; -}; - template void ARM64XEmitter::MOVI2RImpl(ARM64Reg Rd, T imm) { @@ -1844,17 +1818,17 @@ void ARM64XEmitter::MOVI2RImpl(ARM64Reg Rd, T imm) constexpr size_t max_parts = sizeof(T) / 2; - SmallVector best_parts; + Common::SmallVector best_parts; Approach best_approach; u64 best_base; - const auto instructions_required = [](const SmallVector& parts, + const auto instructions_required = [](const Common::SmallVector& parts, Approach approach) { return parts.size() + (approach > Approach::MOVNBase); }; const auto try_base = [&](T base, Approach approach, bool first_time) { - SmallVector parts; + Common::SmallVector parts; for (size_t i = 0; i < max_parts; ++i) { diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 5f3194e09d..20f657698d 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -110,6 +110,7 @@ add_library(common SettingsHandler.h SFMLHelper.cpp SFMLHelper.h + SmallVector.h SocketContext.cpp SocketContext.h SPSCQueue.h diff --git a/Source/Core/Common/SmallVector.h b/Source/Core/Common/SmallVector.h new file mode 100644 index 0000000000..09559ed21a --- /dev/null +++ b/Source/Core/Common/SmallVector.h @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: CC0-1.0 + +#pragma once + +#include +#include +#include + +namespace Common +{ + +// An std::vector-like container that uses no heap allocations but is limited to a maximum size. +template +class SmallVector final +{ +public: + SmallVector() = default; + explicit SmallVector(size_t size) : m_size(size) {} + + void push_back(const T& x) { m_array[m_size++] = x; } + void push_back(T&& x) { m_array[m_size++] = std::move(x); } + + template + T& emplace_back(Args&&... args) + { + return m_array[m_size++] = T{std::forward(args)...}; + } + + T& operator[](size_t i) { return m_array[i]; } + const T& operator[](size_t i) const { return m_array[i]; } + + auto begin() { return m_array.begin(); } + auto end() { return m_array.begin() + m_size; } + + auto begin() const { return m_array.begin(); } + auto end() const { return m_array.begin() + m_size; } + + size_t size() const { return m_size; } + bool empty() const { return m_size == 0; } + +private: + std::array m_array{}; + size_t m_size = 0; +}; + +} // namespace Common diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 1b44f15ec4..810bff4f26 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -143,6 +143,7 @@ + diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp index ad9898b27e..6f9948a68e 100644 --- a/Source/Core/VideoCommon/BPFunctions.cpp +++ b/Source/Core/VideoCommon/BPFunctions.cpp @@ -10,6 +10,7 @@ #include "Common/Assert.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" +#include "Common/SmallVector.h" #include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractGfx.h" @@ -76,26 +77,7 @@ bool ScissorResult::IsWorse(const ScissorRect& lhs, const ScissorRect& rhs) cons namespace { -// Dynamically sized small array of ScissorRanges (used as an heap-less alternative to std::vector -// to reduce allocation overhead) -struct RangeList -{ - static constexpr u32 MAX_RANGES = 9; - - u32 m_num_ranges = 0; - std::array m_ranges{}; - - void AddRange(int offset, int start, int end) - { - DEBUG_ASSERT(m_num_ranges < MAX_RANGES); - m_ranges[m_num_ranges] = ScissorRange(offset, start, end); - m_num_ranges++; - } - auto begin() const { return m_ranges.begin(); } - auto end() const { return m_ranges.begin() + m_num_ranges; } - - u32 size() { return m_num_ranges; } -}; +using RangeList = Common::SmallVector; static RangeList ComputeScissorRanges(int start, int end, int offset, int efb_dim) { @@ -108,7 +90,7 @@ static RangeList ComputeScissorRanges(int start, int end, int offset, int efb_di int new_end = std::clamp(end - new_off + 1, 0, efb_dim); if (new_start < new_end) { - ranges.AddRange(new_off, new_start, new_end); + ranges.emplace_back(new_off, new_start, new_end); } }