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}} {} | 
