From c4f5615c6b908b66eded0317d401ef327abe1dbb Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sat, 25 Mar 2023 15:56:57 -0400 Subject: [PATCH 1/4] CMakeLists: Require a minimum of boost 1.79.0 --- CMakeLists.txt | 2 +- vcpkg.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61c95444fd..a6c43f401b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,7 +210,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) # ======================================================================= # Enforce the search mode of non-required packages for better and shorter failure messages -find_package(Boost 1.81.0 REQUIRED context) +find_package(Boost 1.79.0 REQUIRED context) find_package(enet 1.3 MODULE) find_package(fmt 9 REQUIRED) find_package(inih 52 MODULE COMPONENTS INIReader) diff --git a/vcpkg.json b/vcpkg.json index 9aadd367cc..0352dab77f 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", "name": "yuzu", - "builtin-baseline": "a7b6122f6b6504d16d96117336a0562693579933", + "builtin-baseline": "acc3bcf76b84ae5041c86ab55fe138ae7b8255c7", "version": "1.0", "dependencies": [ "boost-algorithm", From 9971cd1d55b0481a2af74a7694b6dcf686176c7c Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sat, 25 Mar 2023 22:43:55 -0400 Subject: [PATCH 2/4] common: Port boost's hash_value implementation Ports a small subset of boost's hash_value implementation (<= 1.80.0). --- src/common/CMakeLists.txt | 1 + src/common/container_hash.h | 91 +++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 src/common/container_hash.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 90805babe1..c1d2b24a14 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -38,6 +38,7 @@ add_library(common STATIC common_precompiled_headers.h common_types.h concepts.h + container_hash.h demangle.cpp demangle.h div_ceil.h diff --git a/src/common/container_hash.h b/src/common/container_hash.h new file mode 100644 index 0000000000..cfc5dfea8d --- /dev/null +++ b/src/common/container_hash.h @@ -0,0 +1,91 @@ +// SPDX-FileCopyrightText: 2005-2014 Daniel James +// SPDX-FileCopyrightText: 2016 Austin Appleby +// SPDX-License-Identifier: BSL-1.0 + +#include +#include +#include +#include +#include + +namespace Common { + +namespace detail { + +template + requires std::is_unsigned_v +inline std::size_t HashValue(T val) { + const unsigned int size_t_bits = std::numeric_limits::digits; + const unsigned int length = + (std::numeric_limits::digits - 1) / static_cast(size_t_bits); + + std::size_t seed = 0; + + for (unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) { + seed ^= static_cast(val >> i) + (seed << 6) + (seed >> 2); + } + + seed ^= static_cast(val) + (seed << 6) + (seed >> 2); + + return seed; +} + +template +struct HashCombineImpl { + template + static inline T fn(T seed, T value) { + seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + } +}; + +template <> +struct HashCombineImpl<64> { + static inline std::uint64_t fn(std::uint64_t h, std::uint64_t k) { + const std::uint64_t m = (std::uint64_t(0xc6a4a793) << 32) + 0x5bd1e995; + const int r = 47; + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + + // Completely arbitrary number, to prevent 0's + // from hashing to 0. + h += 0xe6546b64; + + return h; + } +}; + +} // namespace detail + +template +inline void HashCombine(std::size_t& seed, const T& v) { + seed = detail::HashCombineImpl::fn(seed, detail::HashValue(v)); +} + +template +inline std::size_t HashRange(It first, It last) { + std::size_t seed = 0; + + for (; first != last; ++first) { + HashCombine::value_type>(seed, *first); + } + + return seed; +} + +template +std::size_t HashValue(const std::array& v) { + return HashRange(v.cbegin(), v.cend()); +} + +template +std::size_t HashValue(const std::vector& v) { + return HashRange(v.cbegin(), v.cend()); +} + +} // namespace Common From f09d192aac68f382b841dd47a3e43a2d8ff87e4d Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sat, 25 Mar 2023 22:45:05 -0400 Subject: [PATCH 3/4] tests: Implement tests for verifying HashValue Values were randomly generated and the verification was done against boost 1.79. --- src/tests/CMakeLists.txt | 1 + src/tests/common/container_hash.cpp | 41 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/tests/common/container_hash.cpp diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index ae84408bcf..39b774c984 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -4,6 +4,7 @@ add_executable(tests common/bit_field.cpp common/cityhash.cpp + common/container_hash.cpp common/fibers.cpp common/host_memory.cpp 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 0000000000..923ac62db7 --- /dev/null +++ b/src/tests/common/container_hash.cpp @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "common/common_types.h" +#include "common/container_hash.h" + +TEST_CASE("ContainerHash", "[common]") { + constexpr std::array U8Values{ + 114, 10, 238, 189, 199, 242, 86, 96, 53, 193, 195, 247, 249, 56, 253, 61, + 205, 3, 172, 4, 210, 197, 43, 72, 103, 8, 99, 89, 5, 97, 68, 196, + }; + constexpr std::array U16Values{ + 61586, 49151, 3313, 11641, 31695, 54795, 46764, 20965, 23287, 14039, 19265, + 49093, 58932, 22518, 27139, 42825, 57417, 54237, 48057, 14586, 42813, 32994, + 33970, 45501, 5619, 15895, 33227, 27509, 25391, 37275, 60218, 17599, + }; + constexpr std::array U32Values{ + 3838402410, 2029146863, 1730869921, 985528872, 186773874, 2094639868, 3324775932, + 1795512424, 2571165571, 3256934519, 2358691590, 2752682538, 1484336451, 378124520, + 3463015699, 3395942161, 1263211979, 3473632889, 3039822212, 2068707357, 2223837919, + 1823232191, 1583884041, 1264393380, 4087566993, 3188607101, 3933680362, 1464520765, + 1786838406, 1311734848, 2773642241, 3993641692, + }; + constexpr std::array U64Values{ + 5908025796157537817, 10947547850358315100, 844798943576724669, 7999662937458523703, + 4006550374705895164, 1832550525423503632, 9323088254855830976, 12028890075598379412, + 6021511300787826236, 7864675007938747948, 18099387408859708806, 6438638299316820708, + 9029399285648501543, 18195459433089960253, 17214335092761966083, 5549347964591337833, + 14899526073304962015, 5058883181561464475, 7436311795731206973, 7535129567768649864, + 1287169596809258072, 8237671246353565927, 1715230541978016153, 8443157615068813300, + 6098675262328527839, 704652094100376853, 1303411723202926503, 7808312933946424854, + 6863726670433556594, 9870361541383217495, 9273671094091079488, 17541434976160119010, + }; + + REQUIRE(Common::HashValue(U8Values) == 5867183267093890552); + REQUIRE(Common::HashValue(U16Values) == 9594135570564347135); + REQUIRE(Common::HashValue(U32Values) == 13123757214696618460); + REQUIRE(Common::HashValue(U64Values) == 7296500016546938380); +} From 49f6deecb8a29fb1f57bdc56dda5fcfbb3d311e3 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sat, 25 Mar 2023 23:02:37 -0400 Subject: [PATCH 4/4] video_core/macro: Make use of Common::HashValue --- src/video_core/macro/macro.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp index 82ad0477d3..905505ca1d 100644 --- a/src/video_core/macro/macro.cpp +++ b/src/video_core/macro/macro.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include "common/container_hash.h" #include #include "common/assert.h" @@ -89,7 +89,7 @@ void MacroEngine::Execute(u32 method, const std::vector& parameters) { if (!mid_method.has_value()) { cache_info.lle_program = Compile(macro_code->second); - cache_info.hash = boost::hash_value(macro_code->second); + cache_info.hash = Common::HashValue(macro_code->second); if (Settings::values.dump_macros) { Dump(cache_info.hash, macro_code->second); } @@ -100,7 +100,7 @@ void MacroEngine::Execute(u32 method, const std::vector& parameters) { code.resize(macro_cached.size() - rebased_method); std::memcpy(code.data(), macro_cached.data() + rebased_method, code.size() * sizeof(u32)); - cache_info.hash = boost::hash_value(code); + cache_info.hash = Common::HashValue(code); cache_info.lle_program = Compile(code); if (Settings::values.dump_macros) { Dump(cache_info.hash, code);