diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 13 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 13 | ||||
| -rw-r--r-- | src/core/core_timing.cpp | 12 | ||||
| -rw-r--r-- | src/core/core_timing_util.cpp | 1 | ||||
| -rw-r--r-- | src/core/core_timing_util.h | 1 | ||||
| -rw-r--r-- | src/core/file_sys/vfs_real.cpp | 80 | ||||
| -rw-r--r-- | src/core/settings.h | 6 |
7 files changed, 83 insertions, 43 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 443ca72eb..b5f28a86e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -143,7 +143,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable& | |||
| 143 | config.wall_clock_cntpct = uses_wall_clock; | 143 | config.wall_clock_cntpct = uses_wall_clock; |
| 144 | 144 | ||
| 145 | // Safe optimizations | 145 | // Safe optimizations |
| 146 | if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) { | 146 | if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) { |
| 147 | if (!Settings::values.cpuopt_page_tables) { | 147 | if (!Settings::values.cpuopt_page_tables) { |
| 148 | config.page_table = nullptr; | 148 | config.page_table = nullptr; |
| 149 | } | 149 | } |
| @@ -170,6 +170,17 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable& | |||
| 170 | } | 170 | } |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | // Unsafe optimizations | ||
| 174 | if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::Unsafe) { | ||
| 175 | config.unsafe_optimizations = true; | ||
| 176 | if (Settings::values.cpuopt_unsafe_unfuse_fma) { | ||
| 177 | config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; | ||
| 178 | } | ||
| 179 | if (Settings::values.cpuopt_unsafe_reduce_fp_error) { | ||
| 180 | config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 173 | return std::make_unique<Dynarmic::A32::Jit>(config); | 184 | return std::make_unique<Dynarmic::A32::Jit>(config); |
| 174 | } | 185 | } |
| 175 | 186 | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index a63a04a25..ce9968724 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp | |||
| @@ -195,7 +195,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable& | |||
| 195 | config.wall_clock_cntpct = uses_wall_clock; | 195 | config.wall_clock_cntpct = uses_wall_clock; |
| 196 | 196 | ||
| 197 | // Safe optimizations | 197 | // Safe optimizations |
| 198 | if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) { | 198 | if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) { |
| 199 | if (!Settings::values.cpuopt_page_tables) { | 199 | if (!Settings::values.cpuopt_page_tables) { |
| 200 | config.page_table = nullptr; | 200 | config.page_table = nullptr; |
| 201 | } | 201 | } |
| @@ -222,6 +222,17 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable& | |||
| 222 | } | 222 | } |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | // Unsafe optimizations | ||
| 226 | if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::Unsafe) { | ||
| 227 | config.unsafe_optimizations = true; | ||
| 228 | if (Settings::values.cpuopt_unsafe_unfuse_fma) { | ||
| 229 | config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; | ||
| 230 | } | ||
| 231 | if (Settings::values.cpuopt_unsafe_reduce_fp_error) { | ||
| 232 | config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; | ||
| 233 | } | ||
| 234 | } | ||
| 235 | |||
| 225 | return std::make_shared<Dynarmic::A64::Jit>(config); | 236 | return std::make_shared<Dynarmic::A64::Jit>(config); |
| 226 | } | 237 | } |
| 227 | 238 | ||
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 71af26ec5..e6c8461a5 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -7,14 +7,14 @@ | |||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include <tuple> | 8 | #include <tuple> |
| 9 | 9 | ||
| 10 | #include "common/assert.h" | ||
| 11 | #include "common/microprofile.h" | 10 | #include "common/microprofile.h" |
| 12 | #include "core/core_timing.h" | 11 | #include "core/core_timing.h" |
| 13 | #include "core/core_timing_util.h" | 12 | #include "core/core_timing_util.h" |
| 13 | #include "core/hardware_properties.h" | ||
| 14 | 14 | ||
| 15 | namespace Core::Timing { | 15 | namespace Core::Timing { |
| 16 | 16 | ||
| 17 | constexpr u64 MAX_SLICE_LENGTH = 4000; | 17 | constexpr s64 MAX_SLICE_LENGTH = 4000; |
| 18 | 18 | ||
| 19 | std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callback) { | 19 | std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callback) { |
| 20 | return std::make_shared<EventType>(std::move(callback), std::move(name)); | 20 | return std::make_shared<EventType>(std::move(callback), std::move(name)); |
| @@ -37,10 +37,8 @@ struct CoreTiming::Event { | |||
| 37 | } | 37 | } |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | CoreTiming::CoreTiming() { | 40 | CoreTiming::CoreTiming() |
| 41 | clock = | 41 | : clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {} |
| 42 | Common::CreateBestMatchingClock(Core::Hardware::BASE_CLOCK_RATE, Core::Hardware::CNTFREQ); | ||
| 43 | } | ||
| 44 | 42 | ||
| 45 | CoreTiming::~CoreTiming() = default; | 43 | CoreTiming::~CoreTiming() = default; |
| 46 | 44 | ||
| @@ -136,7 +134,7 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, | |||
| 136 | 134 | ||
| 137 | void CoreTiming::AddTicks(u64 ticks) { | 135 | void CoreTiming::AddTicks(u64 ticks) { |
| 138 | this->ticks += ticks; | 136 | this->ticks += ticks; |
| 139 | downcount -= ticks; | 137 | downcount -= static_cast<s64>(ticks); |
| 140 | } | 138 | } |
| 141 | 139 | ||
| 142 | void CoreTiming::Idle() { | 140 | void CoreTiming::Idle() { |
diff --git a/src/core/core_timing_util.cpp b/src/core/core_timing_util.cpp index aefc63663..8ce8e602e 100644 --- a/src/core/core_timing_util.cpp +++ b/src/core/core_timing_util.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <limits> | 8 | #include <limits> |
| 9 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | #include "common/uint128.h" | 10 | #include "common/uint128.h" |
| 11 | #include "core/hardware_properties.h" | ||
| 11 | 12 | ||
| 12 | namespace Core::Timing { | 13 | namespace Core::Timing { |
| 13 | 14 | ||
diff --git a/src/core/core_timing_util.h b/src/core/core_timing_util.h index 2ed979e14..e4a046bf9 100644 --- a/src/core/core_timing_util.h +++ b/src/core/core_timing_util.h | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | 6 | ||
| 7 | #include <chrono> | 7 | #include <chrono> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/hardware_properties.h" | ||
| 10 | 9 | ||
| 11 | namespace Core::Timing { | 10 | namespace Core::Timing { |
| 12 | 11 | ||
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 1dbf632c1..488687ba9 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp | |||
| @@ -72,8 +72,10 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const { | |||
| 72 | 72 | ||
| 73 | VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { | 73 | VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { |
| 74 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); | 74 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); |
| 75 | if (cache.find(path) != cache.end()) { | 75 | |
| 76 | auto weak = cache[path]; | 76 | if (const auto weak_iter = cache.find(path); weak_iter != cache.cend()) { |
| 77 | const auto& weak = weak_iter->second; | ||
| 78 | |||
| 77 | if (!weak.expired()) { | 79 | if (!weak.expired()) { |
| 78 | return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, weak.lock(), path, perms)); | 80 | return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, weak.lock(), path, perms)); |
| 79 | } | 81 | } |
| @@ -84,7 +86,7 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { | |||
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | auto backing = std::make_shared<FS::IOFile>(path, ModeFlagsToString(perms).c_str()); | 88 | auto backing = std::make_shared<FS::IOFile>(path, ModeFlagsToString(perms).c_str()); |
| 87 | cache[path] = backing; | 89 | cache.insert_or_assign(path, backing); |
| 88 | 90 | ||
| 89 | // Cannot use make_shared as RealVfsFile constructor is private | 91 | // Cannot use make_shared as RealVfsFile constructor is private |
| 90 | return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, backing, path, perms)); | 92 | return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, backing, path, perms)); |
| @@ -116,11 +118,12 @@ VirtualFile RealVfsFilesystem::CopyFile(std::string_view old_path_, std::string_ | |||
| 116 | VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { | 118 | VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { |
| 117 | const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); | 119 | const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); |
| 118 | const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); | 120 | const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); |
| 121 | const auto cached_file_iter = cache.find(old_path); | ||
| 119 | 122 | ||
| 120 | if (cache.find(old_path) != cache.end()) { | 123 | if (cached_file_iter != cache.cend()) { |
| 121 | auto file = cache[old_path].lock(); | 124 | auto file = cached_file_iter->second.lock(); |
| 122 | 125 | ||
| 123 | if (!cache[old_path].expired()) { | 126 | if (!cached_file_iter->second.expired()) { |
| 124 | file->Close(); | 127 | file->Close(); |
| 125 | } | 128 | } |
| 126 | 129 | ||
| @@ -131,7 +134,7 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_ | |||
| 131 | 134 | ||
| 132 | cache.erase(old_path); | 135 | cache.erase(old_path); |
| 133 | file->Open(new_path, "r+b"); | 136 | file->Open(new_path, "r+b"); |
| 134 | cache[new_path] = file; | 137 | cache.insert_or_assign(new_path, std::move(file)); |
| 135 | } else { | 138 | } else { |
| 136 | UNREACHABLE(); | 139 | UNREACHABLE(); |
| 137 | return nullptr; | 140 | return nullptr; |
| @@ -142,12 +145,15 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_ | |||
| 142 | 145 | ||
| 143 | bool RealVfsFilesystem::DeleteFile(std::string_view path_) { | 146 | bool RealVfsFilesystem::DeleteFile(std::string_view path_) { |
| 144 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); | 147 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); |
| 145 | if (cache.find(path) != cache.end()) { | 148 | const auto cached_iter = cache.find(path); |
| 146 | if (!cache[path].expired()) { | 149 | |
| 147 | cache[path].lock()->Close(); | 150 | if (cached_iter != cache.cend()) { |
| 151 | if (!cached_iter->second.expired()) { | ||
| 152 | cached_iter->second.lock()->Close(); | ||
| 148 | } | 153 | } |
| 149 | cache.erase(path); | 154 | cache.erase(path); |
| 150 | } | 155 | } |
| 156 | |||
| 151 | return FS::Delete(path); | 157 | return FS::Delete(path); |
| 152 | } | 158 | } |
| 153 | 159 | ||
| @@ -192,21 +198,25 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, | |||
| 192 | } | 198 | } |
| 193 | 199 | ||
| 194 | for (auto& kv : cache) { | 200 | for (auto& kv : cache) { |
| 195 | // Path in cache starts with old_path | 201 | // If the path in the cache doesn't start with old_path, then bail on this file. |
| 196 | if (kv.first.rfind(old_path, 0) == 0) { | 202 | if (kv.first.rfind(old_path, 0) != 0) { |
| 197 | const auto file_old_path = | 203 | continue; |
| 198 | FS::SanitizePath(kv.first, FS::DirectorySeparator::PlatformDefault); | 204 | } |
| 199 | const auto file_new_path = | 205 | |
| 200 | FS::SanitizePath(new_path + DIR_SEP + kv.first.substr(old_path.size()), | 206 | const auto file_old_path = |
| 201 | FS::DirectorySeparator::PlatformDefault); | 207 | FS::SanitizePath(kv.first, FS::DirectorySeparator::PlatformDefault); |
| 202 | auto cached = cache[file_old_path]; | 208 | auto file_new_path = FS::SanitizePath(new_path + DIR_SEP + kv.first.substr(old_path.size()), |
| 203 | if (!cached.expired()) { | 209 | FS::DirectorySeparator::PlatformDefault); |
| 204 | auto file = cached.lock(); | 210 | const auto& cached = cache[file_old_path]; |
| 205 | file->Open(file_new_path, "r+b"); | 211 | |
| 206 | cache.erase(file_old_path); | 212 | if (cached.expired()) { |
| 207 | cache[file_new_path] = file; | 213 | continue; |
| 208 | } | ||
| 209 | } | 214 | } |
| 215 | |||
| 216 | auto file = cached.lock(); | ||
| 217 | file->Open(file_new_path, "r+b"); | ||
| 218 | cache.erase(file_old_path); | ||
| 219 | cache.insert_or_assign(std::move(file_new_path), std::move(file)); | ||
| 210 | } | 220 | } |
| 211 | 221 | ||
| 212 | return OpenDirectory(new_path, Mode::ReadWrite); | 222 | return OpenDirectory(new_path, Mode::ReadWrite); |
| @@ -214,15 +224,21 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, | |||
| 214 | 224 | ||
| 215 | bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) { | 225 | bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) { |
| 216 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); | 226 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); |
| 227 | |||
| 217 | for (auto& kv : cache) { | 228 | for (auto& kv : cache) { |
| 218 | // Path in cache starts with old_path | 229 | // If the path in the cache doesn't start with path, then bail on this file. |
| 219 | if (kv.first.rfind(path, 0) == 0) { | 230 | if (kv.first.rfind(path, 0) != 0) { |
| 220 | if (!cache[kv.first].expired()) { | 231 | continue; |
| 221 | cache[kv.first].lock()->Close(); | ||
| 222 | } | ||
| 223 | cache.erase(kv.first); | ||
| 224 | } | 232 | } |
| 233 | |||
| 234 | const auto& entry = cache[kv.first]; | ||
| 235 | if (!entry.expired()) { | ||
| 236 | entry.lock()->Close(); | ||
| 237 | } | ||
| 238 | |||
| 239 | cache.erase(kv.first); | ||
| 225 | } | 240 | } |
| 241 | |||
| 226 | return FS::DeleteDirRecursively(path); | 242 | return FS::DeleteDirRecursively(path); |
| 227 | } | 243 | } |
| 228 | 244 | ||
| @@ -260,14 +276,14 @@ bool RealVfsFile::IsReadable() const { | |||
| 260 | } | 276 | } |
| 261 | 277 | ||
| 262 | std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const { | 278 | std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const { |
| 263 | if (!backing->Seek(offset, SEEK_SET)) { | 279 | if (!backing->Seek(static_cast<s64>(offset), SEEK_SET)) { |
| 264 | return 0; | 280 | return 0; |
| 265 | } | 281 | } |
| 266 | return backing->ReadBytes(data, length); | 282 | return backing->ReadBytes(data, length); |
| 267 | } | 283 | } |
| 268 | 284 | ||
| 269 | std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) { | 285 | std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) { |
| 270 | if (!backing->Seek(offset, SEEK_SET)) { | 286 | if (!backing->Seek(static_cast<s64>(offset), SEEK_SET)) { |
| 271 | return 0; | 287 | return 0; |
| 272 | } | 288 | } |
| 273 | return backing->WriteBytes(data, length); | 289 | return backing->WriteBytes(data, length); |
diff --git a/src/core/settings.h b/src/core/settings.h index bb145f193..3681b5e9d 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -359,7 +359,8 @@ enum class GPUAccuracy : u32 { | |||
| 359 | 359 | ||
| 360 | enum class CPUAccuracy { | 360 | enum class CPUAccuracy { |
| 361 | Accurate = 0, | 361 | Accurate = 0, |
| 362 | DebugMode = 1, | 362 | Unsafe = 1, |
| 363 | DebugMode = 2, | ||
| 363 | }; | 364 | }; |
| 364 | 365 | ||
| 365 | extern bool configuring_global; | 366 | extern bool configuring_global; |
| @@ -419,6 +420,9 @@ struct Values { | |||
| 419 | bool cpuopt_misc_ir; | 420 | bool cpuopt_misc_ir; |
| 420 | bool cpuopt_reduce_misalign_checks; | 421 | bool cpuopt_reduce_misalign_checks; |
| 421 | 422 | ||
| 423 | bool cpuopt_unsafe_unfuse_fma; | ||
| 424 | bool cpuopt_unsafe_reduce_fp_error; | ||
| 425 | |||
| 422 | // Renderer | 426 | // Renderer |
| 423 | Setting<RendererBackend> renderer_backend; | 427 | Setting<RendererBackend> renderer_backend; |
| 424 | bool renderer_debug; | 428 | bool renderer_debug; |