summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt8
-rw-r--r--src/common/arm64/native_clock.cpp72
-rw-r--r--src/common/arm64/native_clock.h47
-rw-r--r--src/common/fs/fs_paths.h2
-rw-r--r--src/common/fs/path_util.cpp2
-rw-r--r--src/common/fs/path_util.h2
-rw-r--r--src/common/settings.cpp10
-rw-r--r--src/common/settings.h4
-rw-r--r--src/common/settings_setting.h2
-rw-r--r--src/common/string_util.cpp5
-rw-r--r--src/common/string_util.h1
-rw-r--r--src/common/wall_clock.cpp8
12 files changed, 159 insertions, 4 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 416203c59..8a1861051 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -189,6 +189,14 @@ if(ARCHITECTURE_x86_64)
189 target_link_libraries(common PRIVATE xbyak::xbyak) 189 target_link_libraries(common PRIVATE xbyak::xbyak)
190endif() 190endif()
191 191
192if (ARCHITECTURE_arm64 AND (ANDROID OR LINUX))
193 target_sources(common
194 PRIVATE
195 arm64/native_clock.cpp
196 arm64/native_clock.h
197 )
198endif()
199
192if (MSVC) 200if (MSVC)
193 target_compile_definitions(common PRIVATE 201 target_compile_definitions(common PRIVATE
194 # The standard library doesn't provide any replacement for codecvt yet 202 # The standard library doesn't provide any replacement for codecvt yet
diff --git a/src/common/arm64/native_clock.cpp b/src/common/arm64/native_clock.cpp
new file mode 100644
index 000000000..88fdba527
--- /dev/null
+++ b/src/common/arm64/native_clock.cpp
@@ -0,0 +1,72 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/arm64/native_clock.h"
5
6namespace Common::Arm64 {
7
8namespace {
9
10NativeClock::FactorType GetFixedPointFactor(u64 num, u64 den) {
11 return (static_cast<NativeClock::FactorType>(num) << 64) / den;
12}
13
14u64 MultiplyHigh(u64 m, NativeClock::FactorType factor) {
15 return static_cast<u64>((m * factor) >> 64);
16}
17
18} // namespace
19
20NativeClock::NativeClock() {
21 const u64 host_cntfrq = GetHostCNTFRQ();
22 ns_cntfrq_factor = GetFixedPointFactor(NsRatio::den, host_cntfrq);
23 us_cntfrq_factor = GetFixedPointFactor(UsRatio::den, host_cntfrq);
24 ms_cntfrq_factor = GetFixedPointFactor(MsRatio::den, host_cntfrq);
25 guest_cntfrq_factor = GetFixedPointFactor(CNTFRQ, host_cntfrq);
26 gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq);
27}
28
29std::chrono::nanoseconds NativeClock::GetTimeNS() const {
30 return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_cntfrq_factor)};
31}
32
33std::chrono::microseconds NativeClock::GetTimeUS() const {
34 return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_cntfrq_factor)};
35}
36
37std::chrono::milliseconds NativeClock::GetTimeMS() const {
38 return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_cntfrq_factor)};
39}
40
41u64 NativeClock::GetCNTPCT() const {
42 return MultiplyHigh(GetHostTicksElapsed(), guest_cntfrq_factor);
43}
44
45u64 NativeClock::GetGPUTick() const {
46 return MultiplyHigh(GetHostTicksElapsed(), gputick_cntfrq_factor);
47}
48
49u64 NativeClock::GetHostTicksNow() const {
50 u64 cntvct_el0 = 0;
51 asm volatile("dsb ish\n\t"
52 "mrs %[cntvct_el0], cntvct_el0\n\t"
53 "dsb ish\n\t"
54 : [cntvct_el0] "=r"(cntvct_el0));
55 return cntvct_el0;
56}
57
58u64 NativeClock::GetHostTicksElapsed() const {
59 return GetHostTicksNow();
60}
61
62bool NativeClock::IsNative() const {
63 return true;
64}
65
66u64 NativeClock::GetHostCNTFRQ() {
67 u64 cntfrq_el0 = 0;
68 asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0));
69 return cntfrq_el0;
70}
71
72} // namespace Common::Arm64
diff --git a/src/common/arm64/native_clock.h b/src/common/arm64/native_clock.h
new file mode 100644
index 000000000..a28b419f2
--- /dev/null
+++ b/src/common/arm64/native_clock.h
@@ -0,0 +1,47 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/wall_clock.h"
7
8namespace Common::Arm64 {
9
10class NativeClock final : public WallClock {
11public:
12 explicit NativeClock();
13
14 std::chrono::nanoseconds GetTimeNS() const override;
15
16 std::chrono::microseconds GetTimeUS() const override;
17
18 std::chrono::milliseconds GetTimeMS() const override;
19
20 u64 GetCNTPCT() const override;
21
22 u64 GetGPUTick() const override;
23
24 u64 GetHostTicksNow() const override;
25
26 u64 GetHostTicksElapsed() const override;
27
28 bool IsNative() const override;
29
30 static u64 GetHostCNTFRQ();
31
32public:
33 using FactorType = unsigned __int128;
34
35 FactorType GetGuestCNTFRQFactor() const {
36 return guest_cntfrq_factor;
37 }
38
39private:
40 FactorType ns_cntfrq_factor;
41 FactorType us_cntfrq_factor;
42 FactorType ms_cntfrq_factor;
43 FactorType guest_cntfrq_factor;
44 FactorType gputick_cntfrq_factor;
45};
46
47} // namespace Common::Arm64
diff --git a/src/common/fs/fs_paths.h b/src/common/fs/fs_paths.h
index 61bac9eba..441c8af97 100644
--- a/src/common/fs/fs_paths.h
+++ b/src/common/fs/fs_paths.h
@@ -18,10 +18,12 @@
18#define LOAD_DIR "load" 18#define LOAD_DIR "load"
19#define LOG_DIR "log" 19#define LOG_DIR "log"
20#define NAND_DIR "nand" 20#define NAND_DIR "nand"
21#define PLAY_TIME_DIR "play_time"
21#define SCREENSHOTS_DIR "screenshots" 22#define SCREENSHOTS_DIR "screenshots"
22#define SDMC_DIR "sdmc" 23#define SDMC_DIR "sdmc"
23#define SHADER_DIR "shader" 24#define SHADER_DIR "shader"
24#define TAS_DIR "tas" 25#define TAS_DIR "tas"
26#define ICONS_DIR "icons"
25 27
26// yuzu-specific files 28// yuzu-specific files
27 29
diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp
index dce219fcf..0abd81a45 100644
--- a/src/common/fs/path_util.cpp
+++ b/src/common/fs/path_util.cpp
@@ -124,10 +124,12 @@ public:
124 GenerateYuzuPath(YuzuPath::LoadDir, yuzu_path / LOAD_DIR); 124 GenerateYuzuPath(YuzuPath::LoadDir, yuzu_path / LOAD_DIR);
125 GenerateYuzuPath(YuzuPath::LogDir, yuzu_path / LOG_DIR); 125 GenerateYuzuPath(YuzuPath::LogDir, yuzu_path / LOG_DIR);
126 GenerateYuzuPath(YuzuPath::NANDDir, yuzu_path / NAND_DIR); 126 GenerateYuzuPath(YuzuPath::NANDDir, yuzu_path / NAND_DIR);
127 GenerateYuzuPath(YuzuPath::PlayTimeDir, yuzu_path / PLAY_TIME_DIR);
127 GenerateYuzuPath(YuzuPath::ScreenshotsDir, yuzu_path / SCREENSHOTS_DIR); 128 GenerateYuzuPath(YuzuPath::ScreenshotsDir, yuzu_path / SCREENSHOTS_DIR);
128 GenerateYuzuPath(YuzuPath::SDMCDir, yuzu_path / SDMC_DIR); 129 GenerateYuzuPath(YuzuPath::SDMCDir, yuzu_path / SDMC_DIR);
129 GenerateYuzuPath(YuzuPath::ShaderDir, yuzu_path / SHADER_DIR); 130 GenerateYuzuPath(YuzuPath::ShaderDir, yuzu_path / SHADER_DIR);
130 GenerateYuzuPath(YuzuPath::TASDir, yuzu_path / TAS_DIR); 131 GenerateYuzuPath(YuzuPath::TASDir, yuzu_path / TAS_DIR);
132 GenerateYuzuPath(YuzuPath::IconsDir, yuzu_path / ICONS_DIR);
131 } 133 }
132 134
133private: 135private:
diff --git a/src/common/fs/path_util.h b/src/common/fs/path_util.h
index ba28964d0..63801c924 100644
--- a/src/common/fs/path_util.h
+++ b/src/common/fs/path_util.h
@@ -20,10 +20,12 @@ enum class YuzuPath {
20 LoadDir, // Where cheat/mod files are stored. 20 LoadDir, // Where cheat/mod files are stored.
21 LogDir, // Where log files are stored. 21 LogDir, // Where log files are stored.
22 NANDDir, // Where the emulated NAND is stored. 22 NANDDir, // Where the emulated NAND is stored.
23 PlayTimeDir, // Where play time data is stored.
23 ScreenshotsDir, // Where yuzu screenshots are stored. 24 ScreenshotsDir, // Where yuzu screenshots are stored.
24 SDMCDir, // Where the emulated SDMC is stored. 25 SDMCDir, // Where the emulated SDMC is stored.
25 ShaderDir, // Where shaders are stored. 26 ShaderDir, // Where shaders are stored.
26 TASDir, // Where TAS scripts are stored. 27 TASDir, // Where TAS scripts are stored.
28 IconsDir, // Where Icons for Windows shortcuts are stored.
27}; 29};
28 30
29/** 31/**
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 4ecaf550b..3fde3cae6 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -130,13 +130,17 @@ void LogSettings() {
130 log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir)); 130 log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir));
131} 131}
132 132
133void UpdateGPUAccuracy() {
134 values.current_gpu_accuracy = values.gpu_accuracy.GetValue();
135}
136
133bool IsGPULevelExtreme() { 137bool IsGPULevelExtreme() {
134 return values.gpu_accuracy.GetValue() == GpuAccuracy::Extreme; 138 return values.current_gpu_accuracy == GpuAccuracy::Extreme;
135} 139}
136 140
137bool IsGPULevelHigh() { 141bool IsGPULevelHigh() {
138 return values.gpu_accuracy.GetValue() == GpuAccuracy::Extreme || 142 return values.current_gpu_accuracy == GpuAccuracy::Extreme ||
139 values.gpu_accuracy.GetValue() == GpuAccuracy::High; 143 values.current_gpu_accuracy == GpuAccuracy::High;
140} 144}
141 145
142bool IsFastmemEnabled() { 146bool IsFastmemEnabled() {
diff --git a/src/common/settings.h b/src/common/settings.h
index 82ec9077e..98ab0ec2e 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -307,6 +307,7 @@ struct Values {
307 Specialization::Default, 307 Specialization::Default,
308 true, 308 true,
309 true}; 309 true};
310 GpuAccuracy current_gpu_accuracy{GpuAccuracy::High};
310 SwitchableSetting<AnisotropyMode, true> max_anisotropy{ 311 SwitchableSetting<AnisotropyMode, true> max_anisotropy{
311 linkage, AnisotropyMode::Automatic, AnisotropyMode::Automatic, AnisotropyMode::X16, 312 linkage, AnisotropyMode::Automatic, AnisotropyMode::Automatic, AnisotropyMode::X16,
312 "max_anisotropy", Category::RendererAdvanced}; 313 "max_anisotropy", Category::RendererAdvanced};
@@ -350,6 +351,8 @@ struct Values {
350 linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug}; 351 linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug};
351 Setting<bool> enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey", 352 Setting<bool> enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey",
352 Category::RendererDebug}; 353 Category::RendererDebug};
354 // TODO: remove this once AMDVLK supports VK_EXT_depth_bias_control
355 bool renderer_amdvlk_depth_bias_workaround{};
353 356
354 // System 357 // System
355 SwitchableSetting<Language, true> language_index{linkage, 358 SwitchableSetting<Language, true> language_index{linkage,
@@ -522,6 +525,7 @@ struct Values {
522 525
523extern Values values; 526extern Values values;
524 527
528void UpdateGPUAccuracy();
525bool IsGPULevelExtreme(); 529bool IsGPULevelExtreme();
526bool IsGPULevelHigh(); 530bool IsGPULevelHigh();
527 531
diff --git a/src/common/settings_setting.h b/src/common/settings_setting.h
index 7be6f26f7..3175ab07d 100644
--- a/src/common/settings_setting.h
+++ b/src/common/settings_setting.h
@@ -187,6 +187,8 @@ public:
187 this->SetValue(input == "true"); 187 this->SetValue(input == "true");
188 } else if constexpr (std::is_same_v<Type, float>) { 188 } else if constexpr (std::is_same_v<Type, float>) {
189 this->SetValue(std::stof(input)); 189 this->SetValue(std::stof(input));
190 } else if constexpr (std::is_same_v<Type, AudioEngine>) {
191 this->SetValue(ToEnum<AudioEngine>(input));
190 } else { 192 } else {
191 this->SetValue(static_cast<Type>(std::stoll(input))); 193 this->SetValue(static_cast<Type>(std::stoll(input)));
192 } 194 }
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index feab1653d..4c7aba3f5 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -135,6 +135,11 @@ std::u16string UTF8ToUTF16(std::string_view input) {
135 return convert.from_bytes(input.data(), input.data() + input.size()); 135 return convert.from_bytes(input.data(), input.data() + input.size());
136} 136}
137 137
138std::u32string UTF8ToUTF32(std::string_view input) {
139 std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
140 return convert.from_bytes(input.data(), input.data() + input.size());
141}
142
138#ifdef _WIN32 143#ifdef _WIN32
139static std::wstring CPToUTF16(u32 code_page, std::string_view input) { 144static std::wstring CPToUTF16(u32 code_page, std::string_view input) {
140 const auto size = 145 const auto size =
diff --git a/src/common/string_util.h b/src/common/string_util.h
index c351f1a0c..9da1ca4e9 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -38,6 +38,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
38 38
39[[nodiscard]] std::string UTF16ToUTF8(std::u16string_view input); 39[[nodiscard]] std::string UTF16ToUTF8(std::u16string_view input);
40[[nodiscard]] std::u16string UTF8ToUTF16(std::string_view input); 40[[nodiscard]] std::u16string UTF8ToUTF16(std::string_view input);
41[[nodiscard]] std::u32string UTF8ToUTF32(std::string_view input);
41 42
42#ifdef _WIN32 43#ifdef _WIN32
43[[nodiscard]] std::string UTF16ToUTF8(std::wstring_view input); 44[[nodiscard]] std::string UTF16ToUTF8(std::wstring_view input);
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp
index 71e15ab4c..caca9a123 100644
--- a/src/common/wall_clock.cpp
+++ b/src/common/wall_clock.cpp
@@ -10,6 +10,10 @@
10#include "common/x64/rdtsc.h" 10#include "common/x64/rdtsc.h"
11#endif 11#endif
12 12
13#if defined(ARCHITECTURE_arm64) && defined(__linux__)
14#include "common/arm64/native_clock.h"
15#endif
16
13namespace Common { 17namespace Common {
14 18
15class StandardWallClock final : public WallClock { 19class StandardWallClock final : public WallClock {
@@ -53,7 +57,7 @@ private:
53}; 57};
54 58
55std::unique_ptr<WallClock> CreateOptimalClock() { 59std::unique_ptr<WallClock> CreateOptimalClock() {
56#ifdef ARCHITECTURE_x86_64 60#if defined(ARCHITECTURE_x86_64)
57 const auto& caps = GetCPUCaps(); 61 const auto& caps = GetCPUCaps();
58 62
59 if (caps.invariant_tsc && caps.tsc_frequency >= std::nano::den) { 63 if (caps.invariant_tsc && caps.tsc_frequency >= std::nano::den) {
@@ -64,6 +68,8 @@ std::unique_ptr<WallClock> CreateOptimalClock() {
64 // - Is not more precise than 1 GHz (1ns resolution) 68 // - Is not more precise than 1 GHz (1ns resolution)
65 return std::make_unique<StandardWallClock>(); 69 return std::make_unique<StandardWallClock>();
66 } 70 }
71#elif defined(ARCHITECTURE_arm64) && defined(__linux__)
72 return std::make_unique<Arm64::NativeClock>();
67#else 73#else
68 return std::make_unique<StandardWallClock>(); 74 return std::make_unique<StandardWallClock>();
69#endif 75#endif