summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-03-15 21:34:22 -0400
committerGravatar Fernando Sahmkow2020-06-27 11:35:52 -0400
commit5d3a2be04f265c2d6a8687431593029f7329060f (patch)
treefa4475df8c0d09aa9e3fe92c6e9ed8dcb5bc267f
parentARM: Addapt to new Exclusive Monitor Interface. (diff)
downloadyuzu-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.cpp11
-rw-r--r--src/core/cpu_manager.cpp11
-rw-r--r--src/core/cpu_manager.h14
-rw-r--r--src/yuzu/configuration/configure_general.ui2
-rw-r--r--src/yuzu/main.cpp29
-rw-r--r--src/yuzu/main.h1
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} {}
21CpuManager::~CpuManager() = default; 22CpuManager::~CpuManager() = default;
22 23
23void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) { 24void 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
34void CpuManager::SetRenderWindow(Core::Frontend::EmuWindow& render_window) {
35 this->render_window = &render_window;
25} 36}
26 37
27void CpuManager::Initialize() { 38void 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;
16class Fiber; 16class Fiber;
17} // namespace Common 17} // namespace Common
18 18
19namespace Core::Frontend {
20class EmuWindow;
21} // namespace Core::Frontend
22
19namespace Core { 23namespace Core {
20 24
21class System; 25class 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
54private: 66private:
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;