diff options
| author | 2020-03-15 21:34:22 -0400 | |
|---|---|---|
| committer | 2020-06-27 11:35:52 -0400 | |
| commit | 5d3a2be04f265c2d6a8687431593029f7329060f (patch) | |
| tree | fa4475df8c0d09aa9e3fe92c6e9ed8dcb5bc267f | |
| parent | ARM: Addapt to new Exclusive Monitor Interface. (diff) | |
| download | yuzu-5d3a2be04f265c2d6a8687431593029f7329060f.tar.gz yuzu-5d3a2be04f265c2d6a8687431593029f7329060f.tar.xz yuzu-5d3a2be04f265c2d6a8687431593029f7329060f.zip | |
GUI: Make multicore only work with Async and add GUI for multicore.
| -rw-r--r-- | src/core/core.cpp | 11 | ||||
| -rw-r--r-- | src/core/cpu_manager.cpp | 11 | ||||
| -rw-r--r-- | src/core/cpu_manager.h | 14 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_general.ui | 2 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 29 | ||||
| -rw-r--r-- | src/yuzu/main.h | 1 |
6 files changed, 63 insertions, 5 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 032da7aa5..0f0eb885a 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -152,8 +152,12 @@ struct System::Impl { | |||
| 152 | 152 | ||
| 153 | device_memory = std::make_unique<Core::DeviceMemory>(system); | 153 | device_memory = std::make_unique<Core::DeviceMemory>(system); |
| 154 | 154 | ||
| 155 | kernel.SetMulticore(Settings::values.use_multi_core); | 155 | is_multicore = Settings::values.use_multi_core; |
| 156 | cpu_manager.SetMulticore(Settings::values.use_multi_core); | 156 | is_async_gpu = is_multicore || Settings::values.use_asynchronous_gpu_emulation; |
| 157 | |||
| 158 | kernel.SetMulticore(is_multicore); | ||
| 159 | cpu_manager.SetMulticore(is_multicore); | ||
| 160 | cpu_manager.SetAsyncGpu(is_async_gpu); | ||
| 157 | 161 | ||
| 158 | core_timing.Initialize([&system]() { system.RegisterHostThread(); }); | 162 | core_timing.Initialize([&system]() { system.RegisterHostThread(); }); |
| 159 | kernel.Initialize(); | 163 | kernel.Initialize(); |
| @@ -395,6 +399,9 @@ struct System::Impl { | |||
| 395 | std::unique_ptr<Core::PerfStats> perf_stats; | 399 | std::unique_ptr<Core::PerfStats> perf_stats; |
| 396 | Core::FrameLimiter frame_limiter; | 400 | Core::FrameLimiter frame_limiter; |
| 397 | 401 | ||
| 402 | bool is_multicore{}; | ||
| 403 | bool is_async_gpu{}; | ||
| 404 | |||
| 398 | std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; | 405 | std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; |
| 399 | }; | 406 | }; |
| 400 | 407 | ||
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index e92b0fb37..d7bd162bc 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/core_timing.h" | 10 | #include "core/core_timing.h" |
| 11 | #include "core/cpu_manager.h" | 11 | #include "core/cpu_manager.h" |
| 12 | #include "core/frontend/emu_window.h" | ||
| 12 | #include "core/gdbstub/gdbstub.h" | 13 | #include "core/gdbstub/gdbstub.h" |
| 13 | #include "core/hle/kernel/kernel.h" | 14 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/kernel/physical_core.h" | 15 | #include "core/hle/kernel/physical_core.h" |
| @@ -21,7 +22,17 @@ CpuManager::CpuManager(System& system) : system{system} {} | |||
| 21 | CpuManager::~CpuManager() = default; | 22 | CpuManager::~CpuManager() = default; |
| 22 | 23 | ||
| 23 | void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) { | 24 | void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) { |
| 25 | if (!cpu_manager.is_async_gpu && !cpu_manager.is_multicore) { | ||
| 26 | cpu_manager.render_window->MakeCurrent(); | ||
| 27 | } | ||
| 24 | cpu_manager.RunThread(core); | 28 | cpu_manager.RunThread(core); |
| 29 | if (!cpu_manager.is_async_gpu && !cpu_manager.is_multicore) { | ||
| 30 | cpu_manager.render_window->DoneCurrent(); | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | void CpuManager::SetRenderWindow(Core::Frontend::EmuWindow& render_window) { | ||
| 35 | this->render_window = &render_window; | ||
| 25 | } | 36 | } |
| 26 | 37 | ||
| 27 | void CpuManager::Initialize() { | 38 | void CpuManager::Initialize() { |
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h index c0e454a7d..37cef2b12 100644 --- a/src/core/cpu_manager.h +++ b/src/core/cpu_manager.h | |||
| @@ -16,6 +16,10 @@ class Event; | |||
| 16 | class Fiber; | 16 | class Fiber; |
| 17 | } // namespace Common | 17 | } // namespace Common |
| 18 | 18 | ||
| 19 | namespace Core::Frontend { | ||
| 20 | class EmuWindow; | ||
| 21 | } // namespace Core::Frontend | ||
| 22 | |||
| 19 | namespace Core { | 23 | namespace Core { |
| 20 | 24 | ||
| 21 | class System; | 25 | class System; |
| @@ -35,6 +39,12 @@ public: | |||
| 35 | void SetMulticore(bool is_multicore) { | 39 | void SetMulticore(bool is_multicore) { |
| 36 | this->is_multicore = is_multicore; | 40 | this->is_multicore = is_multicore; |
| 37 | } | 41 | } |
| 42 | |||
| 43 | /// Sets if emulation is using an asynchronous GPU. | ||
| 44 | void SetAsyncGpu(bool is_async_gpu) { | ||
| 45 | this->is_async_gpu = is_async_gpu; | ||
| 46 | } | ||
| 47 | |||
| 38 | void Initialize(); | 48 | void Initialize(); |
| 39 | void Shutdown(); | 49 | void Shutdown(); |
| 40 | 50 | ||
| @@ -51,6 +61,8 @@ public: | |||
| 51 | return current_core.load(); | 61 | return current_core.load(); |
| 52 | } | 62 | } |
| 53 | 63 | ||
| 64 | void SetRenderWindow(Core::Frontend::EmuWindow& render_window); | ||
| 65 | |||
| 54 | private: | 66 | private: |
| 55 | static void GuestThreadFunction(void* cpu_manager); | 67 | static void GuestThreadFunction(void* cpu_manager); |
| 56 | static void GuestRewindFunction(void* cpu_manager); | 68 | static void GuestRewindFunction(void* cpu_manager); |
| @@ -88,10 +100,12 @@ private: | |||
| 88 | 100 | ||
| 89 | std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{}; | 101 | std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{}; |
| 90 | 102 | ||
| 103 | bool is_async_gpu{}; | ||
| 91 | bool is_multicore{}; | 104 | bool is_multicore{}; |
| 92 | std::atomic<std::size_t> current_core{}; | 105 | std::atomic<std::size_t> current_core{}; |
| 93 | std::size_t preemption_count{}; | 106 | std::size_t preemption_count{}; |
| 94 | static constexpr std::size_t max_cycle_runs = 5; | 107 | static constexpr std::size_t max_cycle_runs = 5; |
| 108 | Core::Frontend::EmuWindow* render_window; | ||
| 95 | 109 | ||
| 96 | System& system; | 110 | System& system; |
| 97 | }; | 111 | }; |
diff --git a/src/yuzu/configuration/configure_general.ui b/src/yuzu/configuration/configure_general.ui index f872bddec..2711116a2 100644 --- a/src/yuzu/configuration/configure_general.ui +++ b/src/yuzu/configuration/configure_general.ui | |||
| @@ -54,7 +54,7 @@ | |||
| 54 | <item> | 54 | <item> |
| 55 | <widget class="QCheckBox" name="use_multi_core"> | 55 | <widget class="QCheckBox" name="use_multi_core"> |
| 56 | <property name="text"> | 56 | <property name="text"> |
| 57 | <string>Emulate CPU in Multiple Cores</string> | 57 | <string>Multicore CPU Emulation</string> |
| 58 | </property> | 58 | </property> |
| 59 | </widget> | 59 | </widget> |
| 60 | </item> | 60 | </item> |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index de0c7fe8c..f1d9ec326 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -534,14 +534,34 @@ void GMainWindow::InitializeWidgets() { | |||
| 534 | if (emulation_running) { | 534 | if (emulation_running) { |
| 535 | return; | 535 | return; |
| 536 | } | 536 | } |
| 537 | Settings::values.use_asynchronous_gpu_emulation = | 537 | bool is_async = !Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core; |
| 538 | !Settings::values.use_asynchronous_gpu_emulation; | 538 | Settings::values.use_asynchronous_gpu_emulation = is_async; |
| 539 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 539 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); |
| 540 | Settings::Apply(); | 540 | Settings::Apply(); |
| 541 | }); | 541 | }); |
| 542 | async_status_button->setText(tr("ASYNC")); | 542 | async_status_button->setText(tr("ASYNC")); |
| 543 | async_status_button->setCheckable(true); | 543 | async_status_button->setCheckable(true); |
| 544 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 544 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); |
| 545 | |||
| 546 | // Setup Multicore button | ||
| 547 | multicore_status_button = new QPushButton(); | ||
| 548 | multicore_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton")); | ||
| 549 | multicore_status_button->setFocusPolicy(Qt::NoFocus); | ||
| 550 | connect(multicore_status_button, &QPushButton::clicked, [&] { | ||
| 551 | if (emulation_running) { | ||
| 552 | return; | ||
| 553 | } | ||
| 554 | Settings::values.use_multi_core = !Settings::values.use_multi_core; | ||
| 555 | bool is_async = Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core; | ||
| 556 | Settings::values.use_asynchronous_gpu_emulation = is_async; | ||
| 557 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | ||
| 558 | multicore_status_button->setChecked(Settings::values.use_multi_core); | ||
| 559 | Settings::Apply(); | ||
| 560 | }); | ||
| 561 | multicore_status_button->setText(tr("MULTICORE")); | ||
| 562 | multicore_status_button->setCheckable(true); | ||
| 563 | multicore_status_button->setChecked(Settings::values.use_multi_core); | ||
| 564 | statusBar()->insertPermanentWidget(0, multicore_status_button); | ||
| 545 | statusBar()->insertPermanentWidget(0, async_status_button); | 565 | statusBar()->insertPermanentWidget(0, async_status_button); |
| 546 | 566 | ||
| 547 | // Setup Renderer API button | 567 | // Setup Renderer API button |
| @@ -1043,6 +1063,7 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1043 | } | 1063 | } |
| 1044 | status_bar_update_timer.start(2000); | 1064 | status_bar_update_timer.start(2000); |
| 1045 | async_status_button->setDisabled(true); | 1065 | async_status_button->setDisabled(true); |
| 1066 | multicore_status_button->setDisabled(true); | ||
| 1046 | renderer_status_button->setDisabled(true); | 1067 | renderer_status_button->setDisabled(true); |
| 1047 | 1068 | ||
| 1048 | if (UISettings::values.hide_mouse) { | 1069 | if (UISettings::values.hide_mouse) { |
| @@ -1130,6 +1151,7 @@ void GMainWindow::ShutdownGame() { | |||
| 1130 | game_fps_label->setVisible(false); | 1151 | game_fps_label->setVisible(false); |
| 1131 | emu_frametime_label->setVisible(false); | 1152 | emu_frametime_label->setVisible(false); |
| 1132 | async_status_button->setEnabled(true); | 1153 | async_status_button->setEnabled(true); |
| 1154 | multicore_status_button->setEnabled(true); | ||
| 1133 | #ifdef HAS_VULKAN | 1155 | #ifdef HAS_VULKAN |
| 1134 | renderer_status_button->setEnabled(true); | 1156 | renderer_status_button->setEnabled(true); |
| 1135 | #endif | 1157 | #endif |
| @@ -1935,7 +1957,10 @@ void GMainWindow::OnConfigure() { | |||
| 1935 | } | 1957 | } |
| 1936 | 1958 | ||
| 1937 | dock_status_button->setChecked(Settings::values.use_docked_mode); | 1959 | dock_status_button->setChecked(Settings::values.use_docked_mode); |
| 1960 | multicore_status_button->setChecked(Settings::values.use_multi_core); | ||
| 1961 | Settings::values.use_asynchronous_gpu_emulation = Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core; | ||
| 1938 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 1962 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); |
| 1963 | |||
| 1939 | #ifdef HAS_VULKAN | 1964 | #ifdef HAS_VULKAN |
| 1940 | renderer_status_button->setChecked(Settings::values.renderer_backend == | 1965 | renderer_status_button->setChecked(Settings::values.renderer_backend == |
| 1941 | Settings::RendererBackend::Vulkan); | 1966 | Settings::RendererBackend::Vulkan); |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index d55e55cc6..5581874ed 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -235,6 +235,7 @@ private: | |||
| 235 | QLabel* game_fps_label = nullptr; | 235 | QLabel* game_fps_label = nullptr; |
| 236 | QLabel* emu_frametime_label = nullptr; | 236 | QLabel* emu_frametime_label = nullptr; |
| 237 | QPushButton* async_status_button = nullptr; | 237 | QPushButton* async_status_button = nullptr; |
| 238 | QPushButton* multicore_status_button = nullptr; | ||
| 238 | QPushButton* renderer_status_button = nullptr; | 239 | QPushButton* renderer_status_button = nullptr; |
| 239 | QPushButton* dock_status_button = nullptr; | 240 | QPushButton* dock_status_button = nullptr; |
| 240 | QTimer status_bar_update_timer; | 241 | QTimer status_bar_update_timer; |