summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/bit_util.h49
-rw-r--r--src/common/common_funcs.h17
-rw-r--r--src/common/nvidia_flags.cpp27
-rw-r--r--src/common/nvidia_flags.h10
-rw-r--r--src/common/ring_buffer.h21
-rw-r--r--src/common/scope_exit.h6
-rw-r--r--src/common/string_util.cpp14
-rw-r--r--src/common/uuid.h4
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}} {}