GUI: Make multicore only work with Async and add GUI for multicore.
This commit is contained in:
parent
25565dffd5
commit
5d3a2be04f
|
@ -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{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Reference in New Issue