GUI: Make multicore only work with Async and add GUI for multicore.

This commit is contained in:
Fernando Sahmkow 2020-03-15 21:34:22 -04:00
parent 25565dffd5
commit 5d3a2be04f
6 changed files with 63 additions and 5 deletions

View File

@ -152,8 +152,12 @@ struct System::Impl {
device_memory = std::make_unique<Core::DeviceMemory>(system); device_memory = std::make_unique<Core::DeviceMemory>(system);
kernel.SetMulticore(Settings::values.use_multi_core); is_multicore = Settings::values.use_multi_core;
cpu_manager.SetMulticore(Settings::values.use_multi_core); is_async_gpu = is_multicore || Settings::values.use_asynchronous_gpu_emulation;
kernel.SetMulticore(is_multicore);
cpu_manager.SetMulticore(is_multicore);
cpu_manager.SetAsyncGpu(is_async_gpu);
core_timing.Initialize([&system]() { system.RegisterHostThread(); }); core_timing.Initialize([&system]() { system.RegisterHostThread(); });
kernel.Initialize(); kernel.Initialize();
@ -395,6 +399,9 @@ struct System::Impl {
std::unique_ptr<Core::PerfStats> perf_stats; std::unique_ptr<Core::PerfStats> perf_stats;
Core::FrameLimiter frame_limiter; Core::FrameLimiter frame_limiter;
bool is_multicore{};
bool is_async_gpu{};
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
}; };

View File

@ -9,6 +9,7 @@
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/cpu_manager.h" #include "core/cpu_manager.h"
#include "core/frontend/emu_window.h"
#include "core/gdbstub/gdbstub.h" #include "core/gdbstub/gdbstub.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/physical_core.h"
@ -21,7 +22,17 @@ CpuManager::CpuManager(System& system) : system{system} {}
CpuManager::~CpuManager() = default; CpuManager::~CpuManager() = default;
void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) { void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) {
if (!cpu_manager.is_async_gpu && !cpu_manager.is_multicore) {
cpu_manager.render_window->MakeCurrent();
}
cpu_manager.RunThread(core); cpu_manager.RunThread(core);
if (!cpu_manager.is_async_gpu && !cpu_manager.is_multicore) {
cpu_manager.render_window->DoneCurrent();
}
}
void CpuManager::SetRenderWindow(Core::Frontend::EmuWindow& render_window) {
this->render_window = &render_window;
} }
void CpuManager::Initialize() { void CpuManager::Initialize() {

View File

@ -16,6 +16,10 @@ class Event;
class Fiber; class Fiber;
} // namespace Common } // namespace Common
namespace Core::Frontend {
class EmuWindow;
} // namespace Core::Frontend
namespace Core { namespace Core {
class System; class System;
@ -35,6 +39,12 @@ public:
void SetMulticore(bool is_multicore) { void SetMulticore(bool is_multicore) {
this->is_multicore = is_multicore; this->is_multicore = is_multicore;
} }
/// Sets if emulation is using an asynchronous GPU.
void SetAsyncGpu(bool is_async_gpu) {
this->is_async_gpu = is_async_gpu;
}
void Initialize(); void Initialize();
void Shutdown(); void Shutdown();
@ -51,6 +61,8 @@ public:
return current_core.load(); return current_core.load();
} }
void SetRenderWindow(Core::Frontend::EmuWindow& render_window);
private: private:
static void GuestThreadFunction(void* cpu_manager); static void GuestThreadFunction(void* cpu_manager);
static void GuestRewindFunction(void* cpu_manager); static void GuestRewindFunction(void* cpu_manager);
@ -88,10 +100,12 @@ private:
std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{}; std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{};
bool is_async_gpu{};
bool is_multicore{}; bool is_multicore{};
std::atomic<std::size_t> current_core{}; std::atomic<std::size_t> current_core{};
std::size_t preemption_count{}; std::size_t preemption_count{};
static constexpr std::size_t max_cycle_runs = 5; static constexpr std::size_t max_cycle_runs = 5;
Core::Frontend::EmuWindow* render_window;
System& system; System& system;
}; };

View File

@ -54,7 +54,7 @@
<item> <item>
<widget class="QCheckBox" name="use_multi_core"> <widget class="QCheckBox" name="use_multi_core">
<property name="text"> <property name="text">
<string>Emulate CPU in Multiple Cores</string> <string>Multicore CPU Emulation</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -534,14 +534,34 @@ void GMainWindow::InitializeWidgets() {
if (emulation_running) { if (emulation_running) {
return; return;
} }
Settings::values.use_asynchronous_gpu_emulation = bool is_async = !Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core;
!Settings::values.use_asynchronous_gpu_emulation; Settings::values.use_asynchronous_gpu_emulation = is_async;
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
Settings::Apply(); Settings::Apply();
}); });
async_status_button->setText(tr("ASYNC")); async_status_button->setText(tr("ASYNC"));
async_status_button->setCheckable(true); async_status_button->setCheckable(true);
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
// Setup Multicore button
multicore_status_button = new QPushButton();
multicore_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
multicore_status_button->setFocusPolicy(Qt::NoFocus);
connect(multicore_status_button, &QPushButton::clicked, [&] {
if (emulation_running) {
return;
}
Settings::values.use_multi_core = !Settings::values.use_multi_core;
bool is_async = Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core;
Settings::values.use_asynchronous_gpu_emulation = is_async;
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
multicore_status_button->setChecked(Settings::values.use_multi_core);
Settings::Apply();
});
multicore_status_button->setText(tr("MULTICORE"));
multicore_status_button->setCheckable(true);
multicore_status_button->setChecked(Settings::values.use_multi_core);
statusBar()->insertPermanentWidget(0, multicore_status_button);
statusBar()->insertPermanentWidget(0, async_status_button); statusBar()->insertPermanentWidget(0, async_status_button);
// Setup Renderer API button // Setup Renderer API button
@ -1043,6 +1063,7 @@ void GMainWindow::BootGame(const QString& filename) {
} }
status_bar_update_timer.start(2000); status_bar_update_timer.start(2000);
async_status_button->setDisabled(true); async_status_button->setDisabled(true);
multicore_status_button->setDisabled(true);
renderer_status_button->setDisabled(true); renderer_status_button->setDisabled(true);
if (UISettings::values.hide_mouse) { if (UISettings::values.hide_mouse) {
@ -1130,6 +1151,7 @@ void GMainWindow::ShutdownGame() {
game_fps_label->setVisible(false); game_fps_label->setVisible(false);
emu_frametime_label->setVisible(false); emu_frametime_label->setVisible(false);
async_status_button->setEnabled(true); async_status_button->setEnabled(true);
multicore_status_button->setEnabled(true);
#ifdef HAS_VULKAN #ifdef HAS_VULKAN
renderer_status_button->setEnabled(true); renderer_status_button->setEnabled(true);
#endif #endif
@ -1935,7 +1957,10 @@ void GMainWindow::OnConfigure() {
} }
dock_status_button->setChecked(Settings::values.use_docked_mode); dock_status_button->setChecked(Settings::values.use_docked_mode);
multicore_status_button->setChecked(Settings::values.use_multi_core);
Settings::values.use_asynchronous_gpu_emulation = Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core;
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
#ifdef HAS_VULKAN #ifdef HAS_VULKAN
renderer_status_button->setChecked(Settings::values.renderer_backend == renderer_status_button->setChecked(Settings::values.renderer_backend ==
Settings::RendererBackend::Vulkan); Settings::RendererBackend::Vulkan);

View File

@ -235,6 +235,7 @@ private:
QLabel* game_fps_label = nullptr; QLabel* game_fps_label = nullptr;
QLabel* emu_frametime_label = nullptr; QLabel* emu_frametime_label = nullptr;
QPushButton* async_status_button = nullptr; QPushButton* async_status_button = nullptr;
QPushButton* multicore_status_button = nullptr;
QPushButton* renderer_status_button = nullptr; QPushButton* renderer_status_button = nullptr;
QPushButton* dock_status_button = nullptr; QPushButton* dock_status_button = nullptr;
QTimer status_bar_update_timer; QTimer status_bar_update_timer;