From 18637766efd1ff9a0c22967553983cfda69c96ca Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 17 Nov 2022 16:36:53 +0100 Subject: MacroHLE: Reduce massive calculations on sizing estimation. --- src/common/CMakeLists.txt | 1 + src/common/range_map.h | 139 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 src/common/range_map.h (limited to 'src/common') diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index eb05e46a8..45332cf95 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -97,6 +97,7 @@ add_library(common STATIC point.h precompiled_headers.h quaternion.h + range_map.h reader_writer_queue.h ring_buffer.h ${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp diff --git a/src/common/range_map.h b/src/common/range_map.h new file mode 100644 index 000000000..993e21643 --- /dev/null +++ b/src/common/range_map.h @@ -0,0 +1,139 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include + +#include "common/common_types.h" + +namespace Common { + +template +class RangeMap { +private: + using KeyT = std::conditional_t, typename KeyTBase, + std::make_signed_t>; + +public: + explicit RangeMap(ValueT null_value_) : null_value{null_value_} { + container.emplace(std::numeric_limits::min(), null_value); + }; + ~RangeMap() = default; + + void Map(KeyTBase address, KeyTBase address_end, ValueT value) { + KeyT new_address = static_cast(address); + KeyT new_address_end = static_cast(address_end); + if (new_address < 0) { + new_address = 0; + } + if (new_address_end < 0) { + new_address_end = 0; + } + InternalMap(new_address, new_address_end, value); + } + + void Unmap(KeyTBase address, KeyTBase address_end) { + Map(address, address_end, null_value); + } + + [[nodiscard]] size_t GetContinousSizeFrom(KeyTBase address) const { + const KeyT new_address = static_cast(address); + if (new_address < 0) { + return 0; + } + return ContinousSizeInternal(new_address); + } + + [[nodiscard]] ValueT GetValueAt(KeyT address) const { + const KeyT new_address = static_cast(address); + if (new_address < 0) { + return null_value; + } + return GetValueInternal(new_address); + } + +private: + using MapType = std::map; + using IteratorType = MapType::iterator; + using ConstIteratorType = MapType::const_iterator; + + size_t ContinousSizeInternal(KeyT address) const { + const auto it = GetFirstElemnentBeforeOrOn(address); + if (it == container.end() || it->second == null_value) { + return 0; + } + const auto it_end = std::next(it); + if (it_end == container.end()) { + return std::numeric_limits::max() - address; + } + return it_end->first - address; + } + + ValueT GetValueInternal(KeyT address) const { + const auto it = GetFirstElemnentBeforeOrOn(address); + if (it == container.end()) { + return null_value; + } + return it->second; + } + + ConstIteratorType GetFirstElemnentBeforeOrOn(KeyT address) const { + auto it = container.lower_bound(address); + if (it == container.begin()) { + return it; + } + if (it != container.end() && (it->first == address)) { + return it; + } + --it; + return it; + } + + ValueT GetFirstValueWithin(KeyT address) { + auto it = container.lower_bound(address); + if (it == container.begin()) { + return it->second; + } + if (it == container.end()) [[unlikely]] { // this would be a bug + return null_value; + } + --it; + return it->second; + } + + ValueT GetLastValueWithin(KeyT address) { + auto it = container.upper_bound(address); + if (it == container.end()) { + return null_value; + } + if (it == container.begin()) [[unlikely]] { // this would be a bug + return it->second; + } + --it; + return it->second; + } + + void InternalMap(KeyT address, KeyT address_end, ValueT value) { + const bool must_add_start = GetFirstValueWithin(address) != value; + const ValueT last_value = GetLastValueWithin(address_end); + const bool must_add_end = last_value != value; + auto it = container.lower_bound(address); + const auto it_end = container.upper_bound(address_end); + while (it != it_end) { + it = container.erase(it); + } + if (must_add_start) { + container.emplace(address, value); + } + if (must_add_end) { + container.emplace(address_end, last_value); + } + } + + ValueT null_value; + MapType container; +}; + +} // namespace Common -- cgit v1.2.3 From d09aa0182f18d1ac338ab47009b42fdeb67497a8 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 24 Dec 2022 19:19:41 -0500 Subject: MacroHLE: Final cleanup and fixes. --- src/common/range_map.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/common') diff --git a/src/common/range_map.h b/src/common/range_map.h index 993e21643..051e713a7 100644 --- a/src/common/range_map.h +++ b/src/common/range_map.h @@ -13,8 +13,8 @@ namespace Common { template class RangeMap { private: - using KeyT = std::conditional_t, typename KeyTBase, - std::make_signed_t>; + using KeyT = + std::conditional_t, KeyTBase, std::make_signed_t>; public: explicit RangeMap(ValueT null_value_) : null_value{null_value_} { @@ -56,8 +56,8 @@ public: private: using MapType = std::map; - using IteratorType = MapType::iterator; - using ConstIteratorType = MapType::const_iterator; + using IteratorType = typename MapType::iterator; + using ConstIteratorType = typename MapType::const_iterator; size_t ContinousSizeInternal(KeyT address) const { const auto it = GetFirstElemnentBeforeOrOn(address); -- cgit v1.2.3 From a0c697124ced080f58866825e2e323e8682bbd7f Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 3 Jan 2023 10:01:25 -0500 Subject: Video_core: Address feedback --- src/common/range_map.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/common') diff --git a/src/common/range_map.h b/src/common/range_map.h index 051e713a7..79c7ef547 100644 --- a/src/common/range_map.h +++ b/src/common/range_map.h @@ -60,7 +60,7 @@ private: using ConstIteratorType = typename MapType::const_iterator; size_t ContinousSizeInternal(KeyT address) const { - const auto it = GetFirstElemnentBeforeOrOn(address); + const auto it = GetFirstElementBeforeOrOn(address); if (it == container.end() || it->second == null_value) { return 0; } @@ -72,14 +72,14 @@ private: } ValueT GetValueInternal(KeyT address) const { - const auto it = GetFirstElemnentBeforeOrOn(address); + const auto it = GetFirstElementBeforeOrOn(address); if (it == container.end()) { return null_value; } return it->second; } - ConstIteratorType GetFirstElemnentBeforeOrOn(KeyT address) const { + ConstIteratorType GetFirstElementBeforeOrOn(KeyT address) const { auto it = container.lower_bound(address); if (it == container.begin()) { return it; -- cgit v1.2.3 From 3ecc03ec1b5f8c48aee4f2e1f1428908647a1cfc Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 4 Jan 2023 14:56:52 -0500 Subject: yuzu-ui: Add setting for disabling macro HLE --- src/common/settings.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/common') diff --git a/src/common/settings.h b/src/common/settings.h index 6b199af93..5017951c5 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -531,6 +531,7 @@ struct Values { Setting reporting_services{false, "reporting_services"}; Setting quest_flag{false, "quest_flag"}; Setting disable_macro_jit{false, "disable_macro_jit"}; + Setting disable_macro_hle{false, "disable_macro_hle"}; Setting extended_logging{false, "extended_logging"}; Setting use_debug_asserts{false, "use_debug_asserts"}; Setting use_auto_stub{false, "use_auto_stub"}; -- cgit v1.2.3