diff options
| author | 2023-03-26 03:46:43 -0400 | |
|---|---|---|
| committer | 2023-03-26 03:46:43 -0400 | |
| commit | 4b508655a42a37f8085ab1b2fd08b0554103c635 (patch) | |
| tree | d177009cf2eaff0a5632bb2968ecff46042f3dac /src | |
| parent | Merge pull request #9985 from liamwhite/funny-meme (diff) | |
| parent | video_core/macro: Make use of Common::HashValue (diff) | |
| download | yuzu-4b508655a42a37f8085ab1b2fd08b0554103c635.tar.gz yuzu-4b508655a42a37f8085ab1b2fd08b0554103c635.tar.xz yuzu-4b508655a42a37f8085ab1b2fd08b0554103c635.zip | |
Merge pull request #9989 from Morph1984/boost-1.79-exact
CMakeLists: Use boost 1.79.0 instead
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/common/container_hash.h | 91 | ||||
| -rw-r--r-- | src/tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/tests/common/container_hash.cpp | 41 | ||||
| -rw-r--r-- | src/video_core/macro/macro.cpp | 6 |
5 files changed, 137 insertions, 3 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 90805babe..c1d2b24a1 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -38,6 +38,7 @@ add_library(common STATIC | |||
| 38 | common_precompiled_headers.h | 38 | common_precompiled_headers.h |
| 39 | common_types.h | 39 | common_types.h |
| 40 | concepts.h | 40 | concepts.h |
| 41 | container_hash.h | ||
| 41 | demangle.cpp | 42 | demangle.cpp |
| 42 | demangle.h | 43 | demangle.h |
| 43 | div_ceil.h | 44 | div_ceil.h |
diff --git a/src/common/container_hash.h b/src/common/container_hash.h new file mode 100644 index 000000000..cfc5dfea8 --- /dev/null +++ b/src/common/container_hash.h | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2005-2014 Daniel James | ||
| 2 | // SPDX-FileCopyrightText: 2016 Austin Appleby | ||
| 3 | // SPDX-License-Identifier: BSL-1.0 | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <cstdint> | ||
| 7 | #include <limits> | ||
| 8 | #include <type_traits> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | namespace Common { | ||
| 12 | |||
| 13 | namespace detail { | ||
| 14 | |||
| 15 | template <typename T> | ||
| 16 | requires std::is_unsigned_v<T> | ||
| 17 | inline std::size_t HashValue(T val) { | ||
| 18 | const unsigned int size_t_bits = std::numeric_limits<std::size_t>::digits; | ||
| 19 | const unsigned int length = | ||
| 20 | (std::numeric_limits<T>::digits - 1) / static_cast<unsigned int>(size_t_bits); | ||
| 21 | |||
| 22 | std::size_t seed = 0; | ||
| 23 | |||
| 24 | for (unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) { | ||
| 25 | seed ^= static_cast<size_t>(val >> i) + (seed << 6) + (seed >> 2); | ||
| 26 | } | ||
| 27 | |||
| 28 | seed ^= static_cast<size_t>(val) + (seed << 6) + (seed >> 2); | ||
| 29 | |||
| 30 | return seed; | ||
| 31 | } | ||
| 32 | |||
| 33 | template <size_t Bits> | ||
| 34 | struct HashCombineImpl { | ||
| 35 | template <typename T> | ||
| 36 | static inline T fn(T seed, T value) { | ||
| 37 | seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2); | ||
| 38 | return seed; | ||
| 39 | } | ||
| 40 | }; | ||
| 41 | |||
| 42 | template <> | ||
| 43 | struct HashCombineImpl<64> { | ||
| 44 | static inline std::uint64_t fn(std::uint64_t h, std::uint64_t k) { | ||
| 45 | const std::uint64_t m = (std::uint64_t(0xc6a4a793) << 32) + 0x5bd1e995; | ||
| 46 | const int r = 47; | ||
| 47 | |||
| 48 | k *= m; | ||
| 49 | k ^= k >> r; | ||
| 50 | k *= m; | ||
| 51 | |||
| 52 | h ^= k; | ||
| 53 | h *= m; | ||
| 54 | |||
| 55 | // Completely arbitrary number, to prevent 0's | ||
| 56 | // from hashing to 0. | ||
| 57 | h += 0xe6546b64; | ||
| 58 | |||
| 59 | return h; | ||
| 60 | } | ||
| 61 | }; | ||
| 62 | |||
| 63 | } // namespace detail | ||
| 64 | |||
| 65 | template <typename T> | ||
| 66 | inline void HashCombine(std::size_t& seed, const T& v) { | ||
| 67 | seed = detail::HashCombineImpl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, detail::HashValue(v)); | ||
| 68 | } | ||
| 69 | |||
| 70 | template <typename It> | ||
| 71 | inline std::size_t HashRange(It first, It last) { | ||
| 72 | std::size_t seed = 0; | ||
| 73 | |||
| 74 | for (; first != last; ++first) { | ||
| 75 | HashCombine<typename std::iterator_traits<It>::value_type>(seed, *first); | ||
| 76 | } | ||
| 77 | |||
| 78 | return seed; | ||
| 79 | } | ||
| 80 | |||
| 81 | template <typename T, size_t Size> | ||
| 82 | std::size_t HashValue(const std::array<T, Size>& v) { | ||
| 83 | return HashRange(v.cbegin(), v.cend()); | ||
| 84 | } | ||
| 85 | |||
| 86 | template <typename T, typename Allocator> | ||
| 87 | std::size_t HashValue(const std::vector<T, Allocator>& v) { | ||
| 88 | return HashRange(v.cbegin(), v.cend()); | ||
| 89 | } | ||
| 90 | |||
| 91 | } // namespace Common | ||
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index ae84408bc..39b774c98 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | add_executable(tests | 4 | add_executable(tests |
| 5 | common/bit_field.cpp | 5 | common/bit_field.cpp |
| 6 | common/cityhash.cpp | 6 | common/cityhash.cpp |
| 7 | common/container_hash.cpp | ||
| 7 | common/fibers.cpp | 8 | common/fibers.cpp |
| 8 | common/host_memory.cpp | 9 | common/host_memory.cpp |
| 9 | common/param_package.cpp | 10 | common/param_package.cpp |
diff --git a/src/tests/common/container_hash.cpp b/src/tests/common/container_hash.cpp new file mode 100644 index 000000000..923ac62db --- /dev/null +++ b/src/tests/common/container_hash.cpp | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <catch2/catch_test_macros.hpp> | ||
| 5 | |||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "common/container_hash.h" | ||
| 8 | |||
| 9 | TEST_CASE("ContainerHash", "[common]") { | ||
| 10 | constexpr std::array<u8, 32> U8Values{ | ||
| 11 | 114, 10, 238, 189, 199, 242, 86, 96, 53, 193, 195, 247, 249, 56, 253, 61, | ||
| 12 | 205, 3, 172, 4, 210, 197, 43, 72, 103, 8, 99, 89, 5, 97, 68, 196, | ||
| 13 | }; | ||
| 14 | constexpr std::array<u16, 32> U16Values{ | ||
| 15 | 61586, 49151, 3313, 11641, 31695, 54795, 46764, 20965, 23287, 14039, 19265, | ||
| 16 | 49093, 58932, 22518, 27139, 42825, 57417, 54237, 48057, 14586, 42813, 32994, | ||
| 17 | 33970, 45501, 5619, 15895, 33227, 27509, 25391, 37275, 60218, 17599, | ||
| 18 | }; | ||
| 19 | constexpr std::array<u32, 32> U32Values{ | ||
| 20 | 3838402410, 2029146863, 1730869921, 985528872, 186773874, 2094639868, 3324775932, | ||
| 21 | 1795512424, 2571165571, 3256934519, 2358691590, 2752682538, 1484336451, 378124520, | ||
| 22 | 3463015699, 3395942161, 1263211979, 3473632889, 3039822212, 2068707357, 2223837919, | ||
| 23 | 1823232191, 1583884041, 1264393380, 4087566993, 3188607101, 3933680362, 1464520765, | ||
| 24 | 1786838406, 1311734848, 2773642241, 3993641692, | ||
| 25 | }; | ||
| 26 | constexpr std::array<u64, 32> U64Values{ | ||
| 27 | 5908025796157537817, 10947547850358315100, 844798943576724669, 7999662937458523703, | ||
| 28 | 4006550374705895164, 1832550525423503632, 9323088254855830976, 12028890075598379412, | ||
| 29 | 6021511300787826236, 7864675007938747948, 18099387408859708806, 6438638299316820708, | ||
| 30 | 9029399285648501543, 18195459433089960253, 17214335092761966083, 5549347964591337833, | ||
| 31 | 14899526073304962015, 5058883181561464475, 7436311795731206973, 7535129567768649864, | ||
| 32 | 1287169596809258072, 8237671246353565927, 1715230541978016153, 8443157615068813300, | ||
| 33 | 6098675262328527839, 704652094100376853, 1303411723202926503, 7808312933946424854, | ||
| 34 | 6863726670433556594, 9870361541383217495, 9273671094091079488, 17541434976160119010, | ||
| 35 | }; | ||
| 36 | |||
| 37 | REQUIRE(Common::HashValue(U8Values) == 5867183267093890552); | ||
| 38 | REQUIRE(Common::HashValue(U16Values) == 9594135570564347135); | ||
| 39 | REQUIRE(Common::HashValue(U32Values) == 13123757214696618460); | ||
| 40 | REQUIRE(Common::HashValue(U64Values) == 7296500016546938380); | ||
| 41 | } | ||
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp index 82ad0477d..905505ca1 100644 --- a/src/video_core/macro/macro.cpp +++ b/src/video_core/macro/macro.cpp | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include <optional> | 6 | #include <optional> |
| 7 | #include <span> | 7 | #include <span> |
| 8 | 8 | ||
| 9 | #include <boost/container_hash/hash.hpp> | 9 | #include "common/container_hash.h" |
| 10 | 10 | ||
| 11 | #include <fstream> | 11 | #include <fstream> |
| 12 | #include "common/assert.h" | 12 | #include "common/assert.h" |
| @@ -89,7 +89,7 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { | |||
| 89 | 89 | ||
| 90 | if (!mid_method.has_value()) { | 90 | if (!mid_method.has_value()) { |
| 91 | cache_info.lle_program = Compile(macro_code->second); | 91 | cache_info.lle_program = Compile(macro_code->second); |
| 92 | cache_info.hash = boost::hash_value(macro_code->second); | 92 | cache_info.hash = Common::HashValue(macro_code->second); |
| 93 | if (Settings::values.dump_macros) { | 93 | if (Settings::values.dump_macros) { |
| 94 | Dump(cache_info.hash, macro_code->second); | 94 | Dump(cache_info.hash, macro_code->second); |
| 95 | } | 95 | } |
| @@ -100,7 +100,7 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { | |||
| 100 | code.resize(macro_cached.size() - rebased_method); | 100 | code.resize(macro_cached.size() - rebased_method); |
| 101 | std::memcpy(code.data(), macro_cached.data() + rebased_method, | 101 | std::memcpy(code.data(), macro_cached.data() + rebased_method, |
| 102 | code.size() * sizeof(u32)); | 102 | code.size() * sizeof(u32)); |
| 103 | cache_info.hash = boost::hash_value(code); | 103 | cache_info.hash = Common::HashValue(code); |
| 104 | cache_info.lle_program = Compile(code); | 104 | cache_info.lle_program = Compile(code); |
| 105 | if (Settings::values.dump_macros) { | 105 | if (Settings::values.dump_macros) { |
| 106 | Dump(cache_info.hash, code); | 106 | Dump(cache_info.hash, code); |