diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/host_memory.cpp | 4 | ||||
| -rw-r--r-- | src/common/logging/backend.cpp | 18 | ||||
| -rw-r--r-- | src/common/page_table.cpp | 58 | ||||
| -rw-r--r-- | src/common/page_table.h | 24 | ||||
| -rw-r--r-- | src/common/settings.cpp | 2 | ||||
| -rw-r--r-- | src/common/settings.h | 4 |
6 files changed, 89 insertions, 21 deletions
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 28949fe5e..c465cfc14 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp | |||
| @@ -327,8 +327,8 @@ private: | |||
| 327 | bool IsNiechePlaceholder(size_t virtual_offset, size_t length) const { | 327 | bool IsNiechePlaceholder(size_t virtual_offset, size_t length) const { |
| 328 | const auto it = placeholders.upper_bound({virtual_offset, virtual_offset + length}); | 328 | const auto it = placeholders.upper_bound({virtual_offset, virtual_offset + length}); |
| 329 | if (it != placeholders.end() && it->lower() == virtual_offset + length) { | 329 | if (it != placeholders.end() && it->lower() == virtual_offset + length) { |
| 330 | const bool is_root = it == placeholders.begin() && virtual_offset == 0; | 330 | return it == placeholders.begin() ? virtual_offset == 0 |
| 331 | return is_root || std::prev(it)->upper() == virtual_offset; | 331 | : std::prev(it)->upper() == virtual_offset; |
| 332 | } | 332 | } |
| 333 | return false; | 333 | return false; |
| 334 | } | 334 | } |
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index c51c05b28..f1c9ed6c4 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp | |||
| @@ -218,19 +218,17 @@ private: | |||
| 218 | Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_) | 218 | Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_) |
| 219 | : filter{filter_}, file_backend{file_backend_filename} {} | 219 | : filter{filter_}, file_backend{file_backend_filename} {} |
| 220 | 220 | ||
| 221 | ~Impl() { | 221 | ~Impl() = default; |
| 222 | StopBackendThread(); | ||
| 223 | } | ||
| 224 | 222 | ||
| 225 | void StartBackendThread() { | 223 | void StartBackendThread() { |
| 226 | backend_thread = std::thread([this] { | 224 | backend_thread = std::jthread([this](std::stop_token stop_token) { |
| 227 | Common::SetCurrentThreadName("yuzu:Log"); | 225 | Common::SetCurrentThreadName("yuzu:Log"); |
| 228 | Entry entry; | 226 | Entry entry; |
| 229 | const auto write_logs = [this, &entry]() { | 227 | const auto write_logs = [this, &entry]() { |
| 230 | ForEachBackend([&entry](Backend& backend) { backend.Write(entry); }); | 228 | ForEachBackend([&entry](Backend& backend) { backend.Write(entry); }); |
| 231 | }; | 229 | }; |
| 232 | while (!stop.stop_requested()) { | 230 | while (!stop_token.stop_requested()) { |
| 233 | entry = message_queue.PopWait(stop.get_token()); | 231 | entry = message_queue.PopWait(stop_token); |
| 234 | if (entry.filename != nullptr) { | 232 | if (entry.filename != nullptr) { |
| 235 | write_logs(); | 233 | write_logs(); |
| 236 | } | 234 | } |
| @@ -244,11 +242,6 @@ private: | |||
| 244 | }); | 242 | }); |
| 245 | } | 243 | } |
| 246 | 244 | ||
| 247 | void StopBackendThread() { | ||
| 248 | stop.request_stop(); | ||
| 249 | backend_thread.join(); | ||
| 250 | } | ||
| 251 | |||
| 252 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, | 245 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, |
| 253 | const char* function, std::string&& message) const { | 246 | const char* function, std::string&& message) const { |
| 254 | using std::chrono::duration_cast; | 247 | using std::chrono::duration_cast; |
| @@ -283,8 +276,7 @@ private: | |||
| 283 | ColorConsoleBackend color_console_backend{}; | 276 | ColorConsoleBackend color_console_backend{}; |
| 284 | FileBackend file_backend; | 277 | FileBackend file_backend; |
| 285 | 278 | ||
| 286 | std::stop_source stop; | 279 | std::jthread backend_thread; |
| 287 | std::thread backend_thread; | ||
| 288 | MPSCQueue<Entry, true> message_queue{}; | 280 | MPSCQueue<Entry, true> message_queue{}; |
| 289 | std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; | 281 | std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; |
| 290 | }; | 282 | }; |
diff --git a/src/common/page_table.cpp b/src/common/page_table.cpp index 9fffd816f..4817b09f9 100644 --- a/src/common/page_table.cpp +++ b/src/common/page_table.cpp | |||
| @@ -10,11 +10,65 @@ PageTable::PageTable() = default; | |||
| 10 | 10 | ||
| 11 | PageTable::~PageTable() noexcept = default; | 11 | PageTable::~PageTable() noexcept = default; |
| 12 | 12 | ||
| 13 | void PageTable::Resize(size_t address_space_width_in_bits, size_t page_size_in_bits) { | 13 | bool PageTable::BeginTraversal(TraversalEntry& out_entry, TraversalContext& out_context, |
| 14 | const size_t num_page_table_entries{1ULL << (address_space_width_in_bits - page_size_in_bits)}; | 14 | u64 address) const { |
| 15 | // Setup invalid defaults. | ||
| 16 | out_entry.phys_addr = 0; | ||
| 17 | out_entry.block_size = page_size; | ||
| 18 | out_context.next_page = 0; | ||
| 19 | |||
| 20 | // Validate that we can read the actual entry. | ||
| 21 | const auto page = address / page_size; | ||
| 22 | if (page >= backing_addr.size()) { | ||
| 23 | return false; | ||
| 24 | } | ||
| 25 | |||
| 26 | // Validate that the entry is mapped. | ||
| 27 | const auto phys_addr = backing_addr[page]; | ||
| 28 | if (phys_addr == 0) { | ||
| 29 | return false; | ||
| 30 | } | ||
| 31 | |||
| 32 | // Populate the results. | ||
| 33 | out_entry.phys_addr = phys_addr + address; | ||
| 34 | out_context.next_page = page + 1; | ||
| 35 | out_context.next_offset = address + page_size; | ||
| 36 | |||
| 37 | return true; | ||
| 38 | } | ||
| 39 | |||
| 40 | bool PageTable::ContinueTraversal(TraversalEntry& out_entry, TraversalContext& context) const { | ||
| 41 | // Setup invalid defaults. | ||
| 42 | out_entry.phys_addr = 0; | ||
| 43 | out_entry.block_size = page_size; | ||
| 44 | |||
| 45 | // Validate that we can read the actual entry. | ||
| 46 | const auto page = context.next_page; | ||
| 47 | if (page >= backing_addr.size()) { | ||
| 48 | return false; | ||
| 49 | } | ||
| 50 | |||
| 51 | // Validate that the entry is mapped. | ||
| 52 | const auto phys_addr = backing_addr[page]; | ||
| 53 | if (phys_addr == 0) { | ||
| 54 | return false; | ||
| 55 | } | ||
| 56 | |||
| 57 | // Populate the results. | ||
| 58 | out_entry.phys_addr = phys_addr + context.next_offset; | ||
| 59 | context.next_page = page + 1; | ||
| 60 | context.next_offset += page_size; | ||
| 61 | |||
| 62 | return true; | ||
| 63 | } | ||
| 64 | |||
| 65 | void PageTable::Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits) { | ||
| 66 | const std::size_t num_page_table_entries{1ULL | ||
| 67 | << (address_space_width_in_bits - page_size_in_bits)}; | ||
| 15 | pointers.resize(num_page_table_entries); | 68 | pointers.resize(num_page_table_entries); |
| 16 | backing_addr.resize(num_page_table_entries); | 69 | backing_addr.resize(num_page_table_entries); |
| 17 | current_address_space_width_in_bits = address_space_width_in_bits; | 70 | current_address_space_width_in_bits = address_space_width_in_bits; |
| 71 | page_size = 1ULL << page_size_in_bits; | ||
| 18 | } | 72 | } |
| 19 | 73 | ||
| 20 | } // namespace Common | 74 | } // namespace Common |
diff --git a/src/common/page_table.h b/src/common/page_table.h index 8267e8b4d..82d91e9f3 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h | |||
| @@ -27,6 +27,16 @@ enum class PageType : u8 { | |||
| 27 | * mimics the way a real CPU page table works. | 27 | * mimics the way a real CPU page table works. |
| 28 | */ | 28 | */ |
| 29 | struct PageTable { | 29 | struct PageTable { |
| 30 | struct TraversalEntry { | ||
| 31 | u64 phys_addr{}; | ||
| 32 | std::size_t block_size{}; | ||
| 33 | }; | ||
| 34 | |||
| 35 | struct TraversalContext { | ||
| 36 | u64 next_page{}; | ||
| 37 | u64 next_offset{}; | ||
| 38 | }; | ||
| 39 | |||
| 30 | /// Number of bits reserved for attribute tagging. | 40 | /// Number of bits reserved for attribute tagging. |
| 31 | /// This can be at most the guaranteed alignment of the pointers in the page table. | 41 | /// This can be at most the guaranteed alignment of the pointers in the page table. |
| 32 | static constexpr int ATTRIBUTE_BITS = 2; | 42 | static constexpr int ATTRIBUTE_BITS = 2; |
| @@ -89,6 +99,10 @@ struct PageTable { | |||
| 89 | PageTable(PageTable&&) noexcept = default; | 99 | PageTable(PageTable&&) noexcept = default; |
| 90 | PageTable& operator=(PageTable&&) noexcept = default; | 100 | PageTable& operator=(PageTable&&) noexcept = default; |
| 91 | 101 | ||
| 102 | bool BeginTraversal(TraversalEntry& out_entry, TraversalContext& out_context, | ||
| 103 | u64 address) const; | ||
| 104 | bool ContinueTraversal(TraversalEntry& out_entry, TraversalContext& context) const; | ||
| 105 | |||
| 92 | /** | 106 | /** |
| 93 | * Resizes the page table to be able to accommodate enough pages within | 107 | * Resizes the page table to be able to accommodate enough pages within |
| 94 | * a given address space. | 108 | * a given address space. |
| @@ -96,9 +110,9 @@ struct PageTable { | |||
| 96 | * @param address_space_width_in_bits The address size width in bits. | 110 | * @param address_space_width_in_bits The address size width in bits. |
| 97 | * @param page_size_in_bits The page size in bits. | 111 | * @param page_size_in_bits The page size in bits. |
| 98 | */ | 112 | */ |
| 99 | void Resize(size_t address_space_width_in_bits, size_t page_size_in_bits); | 113 | void Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits); |
| 100 | 114 | ||
| 101 | size_t GetAddressSpaceBits() const { | 115 | std::size_t GetAddressSpaceBits() const { |
| 102 | return current_address_space_width_in_bits; | 116 | return current_address_space_width_in_bits; |
| 103 | } | 117 | } |
| 104 | 118 | ||
| @@ -110,9 +124,11 @@ struct PageTable { | |||
| 110 | 124 | ||
| 111 | VirtualBuffer<u64> backing_addr; | 125 | VirtualBuffer<u64> backing_addr; |
| 112 | 126 | ||
| 113 | size_t current_address_space_width_in_bits; | 127 | std::size_t current_address_space_width_in_bits{}; |
| 128 | |||
| 129 | u8* fastmem_arena{}; | ||
| 114 | 130 | ||
| 115 | u8* fastmem_arena; | 131 | std::size_t page_size{}; |
| 116 | }; | 132 | }; |
| 117 | 133 | ||
| 118 | } // namespace Common | 134 | } // namespace Common |
diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 6964a8273..877e0faa4 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp | |||
| @@ -167,6 +167,7 @@ void RestoreGlobalState(bool is_powered_on) { | |||
| 167 | 167 | ||
| 168 | // Core | 168 | // Core |
| 169 | values.use_multi_core.SetGlobal(true); | 169 | values.use_multi_core.SetGlobal(true); |
| 170 | values.use_extended_memory_layout.SetGlobal(true); | ||
| 170 | 171 | ||
| 171 | // CPU | 172 | // CPU |
| 172 | values.cpu_accuracy.SetGlobal(true); | 173 | values.cpu_accuracy.SetGlobal(true); |
| @@ -175,6 +176,7 @@ void RestoreGlobalState(bool is_powered_on) { | |||
| 175 | values.cpuopt_unsafe_ignore_standard_fpcr.SetGlobal(true); | 176 | values.cpuopt_unsafe_ignore_standard_fpcr.SetGlobal(true); |
| 176 | values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true); | 177 | values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true); |
| 177 | values.cpuopt_unsafe_fastmem_check.SetGlobal(true); | 178 | values.cpuopt_unsafe_fastmem_check.SetGlobal(true); |
| 179 | values.cpuopt_unsafe_ignore_global_monitor.SetGlobal(true); | ||
| 178 | 180 | ||
| 179 | // Renderer | 181 | // Renderer |
| 180 | values.renderer_backend.SetGlobal(true); | 182 | values.renderer_backend.SetGlobal(true); |
diff --git a/src/common/settings.h b/src/common/settings.h index 9bee6e10f..a37d83fb3 100644 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
| @@ -466,6 +466,7 @@ struct Values { | |||
| 466 | 466 | ||
| 467 | // Core | 467 | // Core |
| 468 | Setting<bool> use_multi_core{true, "use_multi_core"}; | 468 | Setting<bool> use_multi_core{true, "use_multi_core"}; |
| 469 | Setting<bool> use_extended_memory_layout{false, "use_extended_memory_layout"}; | ||
| 469 | 470 | ||
| 470 | // Cpu | 471 | // Cpu |
| 471 | RangedSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto, | 472 | RangedSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto, |
| @@ -483,12 +484,15 @@ struct Values { | |||
| 483 | BasicSetting<bool> cpuopt_misc_ir{true, "cpuopt_misc_ir"}; | 484 | BasicSetting<bool> cpuopt_misc_ir{true, "cpuopt_misc_ir"}; |
| 484 | BasicSetting<bool> cpuopt_reduce_misalign_checks{true, "cpuopt_reduce_misalign_checks"}; | 485 | BasicSetting<bool> cpuopt_reduce_misalign_checks{true, "cpuopt_reduce_misalign_checks"}; |
| 485 | BasicSetting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"}; | 486 | BasicSetting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"}; |
| 487 | BasicSetting<bool> cpuopt_fastmem_exclusives{true, "cpuopt_fastmem_exclusives"}; | ||
| 488 | BasicSetting<bool> cpuopt_recompile_exclusives{true, "cpuopt_recompile_exclusives"}; | ||
| 486 | 489 | ||
| 487 | Setting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"}; | 490 | Setting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"}; |
| 488 | Setting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"}; | 491 | Setting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"}; |
| 489 | Setting<bool> cpuopt_unsafe_ignore_standard_fpcr{true, "cpuopt_unsafe_ignore_standard_fpcr"}; | 492 | Setting<bool> cpuopt_unsafe_ignore_standard_fpcr{true, "cpuopt_unsafe_ignore_standard_fpcr"}; |
| 490 | Setting<bool> cpuopt_unsafe_inaccurate_nan{true, "cpuopt_unsafe_inaccurate_nan"}; | 493 | Setting<bool> cpuopt_unsafe_inaccurate_nan{true, "cpuopt_unsafe_inaccurate_nan"}; |
| 491 | Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"}; | 494 | Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"}; |
| 495 | Setting<bool> cpuopt_unsafe_ignore_global_monitor{true, "cpuopt_unsafe_ignore_global_monitor"}; | ||
| 492 | 496 | ||
| 493 | // Renderer | 497 | // Renderer |
| 494 | RangedSetting<RendererBackend> renderer_backend{ | 498 | RangedSetting<RendererBackend> renderer_backend{ |