1
0
Fork 0
forked from eden-emu/eden

Add cmake option to enable microprofile (#179)

Backported from dd9c743041.

Co-authored-by: PabloMK7 <hackyglitch2@gmail.com>

Co-authored-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: Gamer64 <76565986+Gamer64ytb@users.noreply.github.com>
Reviewed-on: eden-emu/eden#179
Co-authored-by: Gamer64 <gamer64@eden-emu.dev>
Co-committed-by: Gamer64 <gamer64@eden-emu.dev>
This commit is contained in:
Gamer64 2025-08-02 17:22:38 +02:00 committed by crueter
parent b32a667d6f
commit 1f34d836b4
Signed by untrusted user: crueter
GPG key ID: 425ACD2D4830EBC6
17 changed files with 64 additions and 11 deletions

View file

@ -86,6 +86,8 @@ option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF) option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
option(ENABLE_MICROPROFILE "Enables microprofile capabilities" OFF)
option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}") option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}")
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")

View file

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2016 Citra Emulator Project # SPDX-FileCopyrightText: 2016 Citra Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
@ -51,6 +54,11 @@ endif()
# MicroProfile # MicroProfile
add_library(microprofile INTERFACE) add_library(microprofile INTERFACE)
target_include_directories(microprofile INTERFACE ./microprofile) target_include_directories(microprofile INTERFACE ./microprofile)
if (ENABLE_MICROPROFILE)
target_compile_definitions(microprofile INTERFACE MICROPROFILE_ENABLED=1)
else()
target_compile_definitions(microprofile INTERFACE MICROPROFILE_ENABLED=0)
endif()
# GCC bugs # GCC bugs
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND MINGW) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND MINGW)

View file

@ -289,10 +289,12 @@ struct System::Impl {
exit_locked = false; exit_locked = false;
exit_requested = false; exit_requested = false;
#if MICROPROFILE_ENABLED
microprofile_cpu[0] = MICROPROFILE_TOKEN(ARM_CPU0); microprofile_cpu[0] = MICROPROFILE_TOKEN(ARM_CPU0);
microprofile_cpu[1] = MICROPROFILE_TOKEN(ARM_CPU1); microprofile_cpu[1] = MICROPROFILE_TOKEN(ARM_CPU1);
microprofile_cpu[2] = MICROPROFILE_TOKEN(ARM_CPU2); microprofile_cpu[2] = MICROPROFILE_TOKEN(ARM_CPU2);
microprofile_cpu[3] = MICROPROFILE_TOKEN(ARM_CPU3); microprofile_cpu[3] = MICROPROFILE_TOKEN(ARM_CPU3);
#endif
if (Settings::values.enable_renderdoc_hotkey) { if (Settings::values.enable_renderdoc_hotkey) {
renderdoc_api = std::make_unique<Tools::RenderdocAPI>(); renderdoc_api = std::make_unique<Tools::RenderdocAPI>();
@ -573,7 +575,9 @@ struct System::Impl {
std::stop_source stop_event; std::stop_source stop_event;
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
#if MICROPROFILE_ENABLED
std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{}; std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{};
#endif
std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES> std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES>
gpu_dirty_memory_managers; gpu_dirty_memory_managers;
@ -952,6 +956,7 @@ void System::RegisterHostThread() {
impl->kernel.RegisterHostThread(); impl->kernel.RegisterHostThread();
} }
#if MICROPROFILE_ENABLED
void System::EnterCPUProfile() { void System::EnterCPUProfile() {
std::size_t core = impl->kernel.GetCurrentHostThreadID(); std::size_t core = impl->kernel.GetCurrentHostThreadID();
impl->dynarmic_ticks[core] = MicroProfileEnter(impl->microprofile_cpu[core]); impl->dynarmic_ticks[core] = MicroProfileEnter(impl->microprofile_cpu[core]);
@ -961,6 +966,7 @@ void System::ExitCPUProfile() {
std::size_t core = impl->kernel.GetCurrentHostThreadID(); std::size_t core = impl->kernel.GetCurrentHostThreadID();
MicroProfileLeave(impl->microprofile_cpu[core], impl->dynarmic_ticks[core]); MicroProfileLeave(impl->microprofile_cpu[core], impl->dynarmic_ticks[core]);
} }
#endif
bool System::IsMulticore() const { bool System::IsMulticore() const {
return impl->is_multicore; return impl->is_multicore;

View file

@ -396,11 +396,13 @@ public:
/// Register a host thread as an auxiliary thread. /// Register a host thread as an auxiliary thread.
void RegisterHostThread(); void RegisterHostThread();
#if MICROPROFILE_ENABLED
/// Enter CPU Microprofile /// Enter CPU Microprofile
void EnterCPUProfile(); void EnterCPUProfile();
/// Exit CPU Microprofile /// Exit CPU Microprofile
void ExitCPUProfile(); void ExitCPUProfile();
#endif
/// Tells if system is running on multicore. /// Tells if system is running on multicore.
[[nodiscard]] bool IsMulticore() const; [[nodiscard]] bool IsMulticore() const;

View file

@ -61,7 +61,9 @@ void CoreTiming::ThreadEntry(CoreTiming& instance) {
Common::SetCurrentThreadPriority(Common::ThreadPriority::High); Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
instance.on_thread_init(); instance.on_thread_init();
instance.ThreadLoop(); instance.ThreadLoop();
#if MICROPROFILE_ENABLED
MicroProfileOnThreadExit(); MicroProfileOnThreadExit();
#endif
} }
void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) { void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {

View file

@ -201,7 +201,9 @@ void CpuManager::RunThread(std::stop_token token, std::size_t core) {
// Cleanup // Cleanup
SCOPE_EXIT { SCOPE_EXIT {
data.host_context->Exit(); data.host_context->Exit();
#if MICROPROFILE_ENABLED
MicroProfileOnThreadExit(); MicroProfileOnThreadExit();
#endif
}; };
// Running // Running

View file

@ -1278,6 +1278,7 @@ void KernelCore::ExceptionalExitApplication() {
SuspendEmulation(true); SuspendEmulation(true);
} }
#if MICROPROFILE_ENABLED
void KernelCore::EnterSVCProfile() { void KernelCore::EnterSVCProfile() {
impl->svc_ticks[CurrentPhysicalCoreIndex()] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC)); impl->svc_ticks[CurrentPhysicalCoreIndex()] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC));
} }
@ -1285,6 +1286,7 @@ void KernelCore::EnterSVCProfile() {
void KernelCore::ExitSVCProfile() { void KernelCore::ExitSVCProfile() {
MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]); MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]);
} }
#endif
Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() { Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() {
return impl->slab_resource_counts; return impl->slab_resource_counts;

View file

@ -271,9 +271,11 @@ public:
bool IsShuttingDown() const; bool IsShuttingDown() const;
#if MICROPROFILE_ENABLED
void EnterSVCProfile(); void EnterSVCProfile();
void ExitSVCProfile(); void ExitSVCProfile();
#endif
/// Workaround for single-core mode when preempting threads while idle. /// Workaround for single-core mode when preempting threads while idle.
bool IsPhantomModeForSingleCore() const; bool IsPhantomModeForSingleCore() const;

View file

@ -27,7 +27,9 @@ void PhysicalCore::RunThread(Kernel::KThread* thread) {
interface->Initialize(); interface->Initialize();
const auto EnterContext = [&]() { const auto EnterContext = [&]() {
#if MICROPROFILE_ENABLED
system.EnterCPUProfile(); system.EnterCPUProfile();
#endif
// Lock the core context. // Lock the core context.
std::scoped_lock lk{m_guard}; std::scoped_lock lk{m_guard};
@ -59,7 +61,9 @@ void PhysicalCore::RunThread(Kernel::KThread* thread) {
m_arm_interface = nullptr; m_arm_interface = nullptr;
m_current_thread = nullptr; m_current_thread = nullptr;
#if MICROPROFILE_ENABLED
system.ExitCPUProfile(); system.ExitCPUProfile();
#endif
}; };
while (true) { while (true) {

View file

@ -4428,7 +4428,9 @@ void Call(Core::System& system, u32 imm) {
std::array<uint64_t, 8> args; std::array<uint64_t, 8> args;
kernel.CurrentPhysicalCore().SaveSvcArguments(process, args); kernel.CurrentPhysicalCore().SaveSvcArguments(process, args);
#if MICROPROFILE_ENABLED
kernel.EnterSVCProfile(); kernel.EnterSVCProfile();
#endif
if (process.Is64Bit()) { if (process.Is64Bit()) {
Call64(system, imm, args); Call64(system, imm, args);
@ -4436,7 +4438,9 @@ void Call(Core::System& system, u32 imm) {
Call32(system, imm, args); Call32(system, imm, args);
} }
#if MICROPROFILE_ENABLED
kernel.ExitSVCProfile(); kernel.ExitSVCProfile();
#endif
kernel.CurrentPhysicalCore().LoadSvcArguments(process, args); kernel.CurrentPhysicalCore().LoadSvcArguments(process, args);
} }

View file

@ -219,9 +219,11 @@ private:
MicroProfileOnThreadCreate(name.c_str()); MicroProfileOnThreadCreate(name.c_str());
// Cleanup // Cleanup
#if MICROPROFILE_ENABLED
SCOPE_EXIT { SCOPE_EXIT {
MicroProfileOnThreadExit(); MicroProfileOnThreadExit();
}; };
#endif
Common::SetCurrentThreadName(name.c_str()); Common::SetCurrentThreadName(name.c_str());
Common::SetCurrentThreadPriority(Common::ThreadPriority::High); Common::SetCurrentThreadPriority(Common::ThreadPriority::High);

View file

@ -23,9 +23,11 @@ static void RunThread(std::stop_token stop_token, Core::System& system,
Tegra::Control::Scheduler& scheduler, SynchState& state) { Tegra::Control::Scheduler& scheduler, SynchState& state) {
std::string name = "GPU"; std::string name = "GPU";
MicroProfileOnThreadCreate(name.c_str()); MicroProfileOnThreadCreate(name.c_str());
#if MICROPROFILE_ENABLED
SCOPE_EXIT { SCOPE_EXIT {
MicroProfileOnThreadExit(); MicroProfileOnThreadExit();
}; };
#endif
Common::SetCurrentThreadName(name.c_str()); Common::SetCurrentThreadName(name.c_str());
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);

View file

@ -1,6 +1,11 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2015 Citra Emulator Project // SPDX-FileCopyrightText: 2015 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#if MICROPROFILE_ENABLED
#include <QAction> #include <QAction>
#include <QLayout> #include <QLayout>
#include <QMouseEvent> #include <QMouseEvent>
@ -14,7 +19,7 @@
// Include the implementation of the UI in this file. This isn't in microprofile.cpp because the // Include the implementation of the UI in this file. This isn't in microprofile.cpp because the
// non-Qt frontends don't need it (and don't implement the UI drawing hooks either). // non-Qt frontends don't need it (and don't implement the UI drawing hooks either).
#if MICROPROFILE_ENABLED
#define MICROPROFILEUI_IMPL 1 #define MICROPROFILEUI_IMPL 1
#include "common/microprofileui.h" #include "common/microprofileui.h"
@ -43,8 +48,6 @@ private:
qreal x_scale = 1.0, y_scale = 1.0; qreal x_scale = 1.0, y_scale = 1.0;
}; };
#endif
MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Dialog) { MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Dialog) {
setObjectName(QStringLiteral("MicroProfile")); setObjectName(QStringLiteral("MicroProfile"));
setWindowTitle(tr("&MicroProfile")); setWindowTitle(tr("&MicroProfile"));
@ -52,8 +55,6 @@ MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Di
// Enable the maximize button // Enable the maximize button
setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint); setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint);
#if MICROPROFILE_ENABLED
MicroProfileWidget* widget = new MicroProfileWidget(this); MicroProfileWidget* widget = new MicroProfileWidget(this);
QLayout* layout = new QVBoxLayout(this); QLayout* layout = new QVBoxLayout(this);
@ -66,7 +67,6 @@ MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Di
setFocusProxy(widget); setFocusProxy(widget);
widget->setFocusPolicy(Qt::StrongFocus); widget->setFocusPolicy(Qt::StrongFocus);
widget->setFocus(); widget->setFocus();
#endif
} }
QAction* MicroProfileDialog::toggleViewAction() { QAction* MicroProfileDialog::toggleViewAction() {
@ -94,8 +94,6 @@ void MicroProfileDialog::hideEvent(QHideEvent* ev) {
QWidget::hideEvent(ev); QWidget::hideEvent(ev);
} }
#if MICROPROFILE_ENABLED
/// There's no way to pass a user pointer to MicroProfile, so this variable is used to make the /// There's no way to pass a user pointer to MicroProfile, so this variable is used to make the
/// QPainter available inside the drawing callbacks. /// QPainter available inside the drawing callbacks.
static QPainter* mp_painter = nullptr; static QPainter* mp_painter = nullptr;

View file

@ -1,8 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2015 Citra Emulator Project // SPDX-FileCopyrightText: 2015 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
#if MICROPROFILE_ENABLED
#include <QWidget> #include <QWidget>
class QAction; class QAction;
@ -25,3 +30,4 @@ protected:
private: private:
QAction* toggle_view_action = nullptr; QAction* toggle_view_action = nullptr;
}; };
#endif

View file

@ -1348,6 +1348,11 @@ void GMainWindow::InitializeDebugWidgets() {
microProfileDialog = new MicroProfileDialog(this); microProfileDialog = new MicroProfileDialog(this);
microProfileDialog->hide(); microProfileDialog->hide();
debug_menu->addAction(microProfileDialog->toggleViewAction()); debug_menu->addAction(microProfileDialog->toggleViewAction());
#else
auto micro_profile_stub = new QAction(tr("MicroProfile (unavailable)"), this);
micro_profile_stub->setEnabled(false);
micro_profile_stub->setChecked(false);
debug_menu->addAction(micro_profile_stub);
#endif #endif
waitTreeWidget = new WaitTreeWidget(*system, this); waitTreeWidget = new WaitTreeWidget(*system, this);
@ -5630,10 +5635,13 @@ int main(int argc, char* argv[]) {
#endif #endif
Common::DetachedTasks detached_tasks; Common::DetachedTasks detached_tasks;
#if MICROPROFILE_ENABLED
MicroProfileOnThreadCreate("Frontend"); MicroProfileOnThreadCreate("Frontend");
SCOPE_EXIT { SCOPE_EXIT {
MicroProfileShutdown(); MicroProfileShutdown();
}; };
#endif
Common::ConfigureNvidiaEnvironmentFlags(); Common::ConfigureNvidiaEnvironmentFlags();

View file

@ -43,7 +43,9 @@ class GameList;
class GImageInfo; class GImageInfo;
class GRenderWindow; class GRenderWindow;
class LoadingScreen; class LoadingScreen;
#if MICROPROFILE_ENABLED
class MicroProfileDialog; class MicroProfileDialog;
#endif
class OverlayDialog; class OverlayDialog;
class ProfilerWidget; class ProfilerWidget;
class ControllerDialog; class ControllerDialog;
@ -565,7 +567,9 @@ private:
// Debugger panes // Debugger panes
ProfilerWidget* profilerWidget; ProfilerWidget* profilerWidget;
#if MICROPROFILE_ENABLED
MicroProfileDialog* microProfileDialog; MicroProfileDialog* microProfileDialog;
#endif
WaitTreeWidget* waitTreeWidget; WaitTreeWidget* waitTreeWidget;
ControllerDialog* controller_dialog; ControllerDialog* controller_dialog;

View file

@ -4,9 +4,6 @@
// SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-FileCopyrightText: 2014 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
#include <memory> #include <memory>
@ -338,10 +335,12 @@ int main(int argc, char** argv) {
LocalFree(argv_w); LocalFree(argv_w);
#endif #endif
#if MICROPROFILE_ENABLED
MicroProfileOnThreadCreate("EmuThread"); MicroProfileOnThreadCreate("EmuThread");
SCOPE_EXIT { SCOPE_EXIT {
MicroProfileShutdown(); MicroProfileShutdown();
}; };
#endif
Common::ConfigureNvidiaEnvironmentFlags(); Common::ConfigureNvidiaEnvironmentFlags();