diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/common/bit_util.h | 49 | ||||
| -rw-r--r-- | src/common/common_funcs.h | 17 | ||||
| -rw-r--r-- | src/common/nvidia_flags.cpp | 27 | ||||
| -rw-r--r-- | src/common/nvidia_flags.h | 10 | ||||
| -rw-r--r-- | src/common/ring_buffer.h | 21 | ||||
| -rw-r--r-- | src/common/scope_exit.h | 6 | ||||
| -rw-r--r-- | src/common/string_util.cpp | 14 | ||||
| -rw-r--r-- | src/common/uuid.h | 4 |
9 files changed, 88 insertions, 62 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index f77575a00..bfd11e76d 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -138,6 +138,8 @@ add_library(common STATIC microprofile.h microprofileui.h misc.cpp + nvidia_flags.cpp + nvidia_flags.h page_table.cpp page_table.h param_package.cpp diff --git a/src/common/bit_util.h b/src/common/bit_util.h index 685e7fc9b..64520ca4e 100644 --- a/src/common/bit_util.h +++ b/src/common/bit_util.h @@ -4,13 +4,10 @@ #pragma once +#include <bit> #include <climits> #include <cstddef> -#ifdef _MSC_VER -#include <intrin.h> -#endif - #include "common/common_types.h" namespace Common { @@ -21,48 +18,30 @@ template <typename T> return sizeof(T) * CHAR_BIT; } -#ifdef _MSC_VER - -[[nodiscard]] inline u32 MostSignificantBit32(const u32 value) { - unsigned long result; - _BitScanReverse(&result, value); - return static_cast<u32>(result); -} - -[[nodiscard]] inline u32 MostSignificantBit64(const u64 value) { - unsigned long result; - _BitScanReverse64(&result, value); - return static_cast<u32>(result); -} - -#else - -[[nodiscard]] inline u32 MostSignificantBit32(const u32 value) { - return 31U - static_cast<u32>(__builtin_clz(value)); +[[nodiscard]] constexpr u32 MostSignificantBit32(const u32 value) { + return 31U - static_cast<u32>(std::countl_zero(value)); } -[[nodiscard]] inline u32 MostSignificantBit64(const u64 value) { - return 63U - static_cast<u32>(__builtin_clzll(value)); +[[nodiscard]] constexpr u32 MostSignificantBit64(const u64 value) { + return 63U - static_cast<u32>(std::countl_zero(value)); } -#endif - -[[nodiscard]] inline u32 Log2Floor32(const u32 value) { +[[nodiscard]] constexpr u32 Log2Floor32(const u32 value) { return MostSignificantBit32(value); } -[[nodiscard]] inline u32 Log2Ceil32(const u32 value) { - const u32 log2_f = Log2Floor32(value); - return log2_f + ((value ^ (1U << log2_f)) != 0U); +[[nodiscard]] constexpr u32 Log2Floor64(const u64 value) { + return MostSignificantBit64(value); } -[[nodiscard]] inline u32 Log2Floor64(const u64 value) { - return MostSignificantBit64(value); +[[nodiscard]] constexpr u32 Log2Ceil32(const u32 value) { + const u32 log2_f = Log2Floor32(value); + return log2_f + static_cast<u32>((value ^ (1U << log2_f)) != 0U); } -[[nodiscard]] inline u32 Log2Ceil64(const u64 value) { - const u64 log2_f = static_cast<u64>(Log2Floor64(value)); - return static_cast<u32>(log2_f + ((value ^ (1ULL << log2_f)) != 0ULL)); +[[nodiscard]] constexpr u32 Log2Ceil64(const u64 value) { + const u64 log2_f = Log2Floor64(value); + return static_cast<u32>(log2_f + static_cast<u64>((value ^ (1ULL << log2_f)) != 0ULL)); } } // namespace Common diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 75f3027fb..71b64e32a 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h @@ -97,10 +97,27 @@ __declspec(dllimport) void __stdcall DebugBreak(void); #define R_UNLESS(expr, res) \ { \ if (!(expr)) { \ + if (res.IsError()) { \ + LOG_ERROR(Kernel, "Failed with result: {}", res.raw); \ + } \ return res; \ } \ } +#define R_SUCCEEDED(res) (res.IsSuccess()) + +/// Evaluates an expression that returns a result, and returns the result if it would fail. +#define R_TRY(res_expr) \ + { \ + const auto _tmp_r_try_rc = (res_expr); \ + if (_tmp_r_try_rc.IsError()) { \ + return _tmp_r_try_rc; \ + } \ + } + +/// Evaluates a boolean expression, and succeeds if that expression is true. +#define R_SUCCEED_IF(expr) R_UNLESS(!(expr), RESULT_SUCCESS) + namespace Common { [[nodiscard]] constexpr u32 MakeMagic(char a, char b, char c, char d) { diff --git a/src/common/nvidia_flags.cpp b/src/common/nvidia_flags.cpp new file mode 100644 index 000000000..d537517db --- /dev/null +++ b/src/common/nvidia_flags.cpp @@ -0,0 +1,27 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <filesystem> +#include <stdlib.h> + +#include <fmt/format.h> + +#include "common/file_util.h" +#include "common/nvidia_flags.h" + +namespace Common { + +void ConfigureNvidiaEnvironmentFlags() { +#ifdef _WIN32 + const std::string shader_path = Common::FS::SanitizePath( + fmt::format("{}/nvidia/", Common::FS::GetUserPath(Common::FS::UserPath::ShaderDir))); + const std::string windows_path = + Common::FS::SanitizePath(shader_path, Common::FS::DirectorySeparator::BackwardSlash); + void(Common::FS::CreateFullPath(shader_path + '/')); + void(_putenv(fmt::format("__GL_SHADER_DISK_CACHE_PATH={}", windows_path).c_str())); + void(_putenv("__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1")); +#endif +} + +} // namespace Common diff --git a/src/common/nvidia_flags.h b/src/common/nvidia_flags.h new file mode 100644 index 000000000..75a0233ac --- /dev/null +++ b/src/common/nvidia_flags.h @@ -0,0 +1,10 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +namespace Common { + +/// Configure platform specific flags for Nvidia's driver +void ConfigureNvidiaEnvironmentFlags(); + +} // namespace Common diff --git a/src/common/ring_buffer.h b/src/common/ring_buffer.h index 138fa0131..4a8d09806 100644 --- a/src/common/ring_buffer.h +++ b/src/common/ring_buffer.h @@ -19,15 +19,14 @@ namespace Common { /// SPSC ring buffer /// @tparam T Element type /// @tparam capacity Number of slots in ring buffer -/// @tparam granularity Slot size in terms of number of elements -template <typename T, std::size_t capacity, std::size_t granularity = 1> +template <typename T, std::size_t capacity> class RingBuffer { - /// A "slot" is made of `granularity` elements of `T`. - static constexpr std::size_t slot_size = granularity * sizeof(T); + /// A "slot" is made of a single `T`. + static constexpr std::size_t slot_size = sizeof(T); // T must be safely memcpy-able and have a trivial default constructor. static_assert(std::is_trivial_v<T>); // Ensure capacity is sensible. - static_assert(capacity < std::numeric_limits<std::size_t>::max() / 2 / granularity); + static_assert(capacity < std::numeric_limits<std::size_t>::max() / 2); static_assert((capacity & (capacity - 1)) == 0, "capacity must be a power of two"); // Ensure lock-free. static_assert(std::atomic_size_t::is_always_lock_free); @@ -47,7 +46,7 @@ public: const std::size_t second_copy = push_count - first_copy; const char* in = static_cast<const char*>(new_slots); - std::memcpy(m_data.data() + pos * granularity, in, first_copy * slot_size); + std::memcpy(m_data.data() + pos, in, first_copy * slot_size); in += first_copy * slot_size; std::memcpy(m_data.data(), in, second_copy * slot_size); @@ -74,7 +73,7 @@ public: const std::size_t second_copy = pop_count - first_copy; char* out = static_cast<char*>(output); - std::memcpy(out, m_data.data() + pos * granularity, first_copy * slot_size); + std::memcpy(out, m_data.data() + pos, first_copy * slot_size); out += first_copy * slot_size; std::memcpy(out, m_data.data(), second_copy * slot_size); @@ -84,9 +83,9 @@ public: } std::vector<T> Pop(std::size_t max_slots = ~std::size_t(0)) { - std::vector<T> out(std::min(max_slots, capacity) * granularity); - const std::size_t count = Pop(out.data(), out.size() / granularity); - out.resize(count * granularity); + std::vector<T> out(std::min(max_slots, capacity)); + const std::size_t count = Pop(out.data(), out.size()); + out.resize(count); return out; } @@ -113,7 +112,7 @@ private: alignas(128) std::atomic_size_t m_write_index{0}; #endif - std::array<T, granularity * capacity> m_data; + std::array<T, capacity> m_data; }; } // namespace Common diff --git a/src/common/scope_exit.h b/src/common/scope_exit.h index fa46cb394..35dac3a8f 100644 --- a/src/common/scope_exit.h +++ b/src/common/scope_exit.h @@ -49,3 +49,9 @@ ScopeExitHelper<Func> ScopeExit(Func&& func) { * \endcode */ #define SCOPE_EXIT(body) auto CONCAT2(scope_exit_helper_, __LINE__) = detail::ScopeExit([&]() body) + +/** + * This macro is similar to SCOPE_EXIT, except the object is caller managed. This is intended to be + * used when the caller might want to cancel the ScopeExit. + */ +#define SCOPE_GUARD(body) detail::ScopeExit([&]() body) diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 4cba2aaa4..7b614ad89 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -141,27 +141,13 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st } std::string UTF16ToUTF8(const std::u16string& input) { -#ifdef _MSC_VER - // Workaround for missing char16_t/char32_t instantiations in MSVC2017 - std::wstring_convert<std::codecvt_utf8_utf16<__int16>, __int16> convert; - std::basic_string<__int16> tmp_buffer(input.cbegin(), input.cend()); - return convert.to_bytes(tmp_buffer); -#else std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; return convert.to_bytes(input); -#endif } std::u16string UTF8ToUTF16(const std::string& input) { -#ifdef _MSC_VER - // Workaround for missing char16_t/char32_t instantiations in MSVC2017 - std::wstring_convert<std::codecvt_utf8_utf16<__int16>, __int16> convert; - auto tmp_buffer = convert.from_bytes(input); - return std::u16string(tmp_buffer.cbegin(), tmp_buffer.cend()); -#else std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; return convert.from_bytes(input); -#endif } #ifdef _WIN32 diff --git a/src/common/uuid.h b/src/common/uuid.h index 4ab9a25f0..2e7a18405 100644 --- a/src/common/uuid.h +++ b/src/common/uuid.h @@ -14,8 +14,8 @@ constexpr u128 INVALID_UUID{{0, 0}}; struct UUID { // UUIDs which are 0 are considered invalid! - u128 uuid = INVALID_UUID; - constexpr UUID() = default; + u128 uuid; + UUID() = default; constexpr explicit UUID(const u128& id) : uuid{id} {} constexpr explicit UUID(const u64 lo, const u64 hi) : uuid{{lo, hi}} {} |
