core: Make PICA debugging a toggleable feature (#2254)

This commit is contained in:
PabloMK7 2026-07-03 11:00:56 +02:00 committed by GitHub
parent 77cb5cecd8
commit fcb10fb899
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 87 additions and 51 deletions

View File

@ -32,6 +32,7 @@ foreach(KEY IN ITEMS
"physical_device" "physical_device"
"use_gles" "use_gles"
"renderer_debug" "renderer_debug"
"pica_debugging"
"dump_command_buffers" "dump_command_buffers"
"spirv_shader_gen" "spirv_shader_gen"
"disable_spirv_optimizer" "disable_spirv_optimizer"

View File

@ -314,6 +314,7 @@ void Config::ReadValues() {
Settings::values.record_frame_times = Settings::values.record_frame_times =
android_config->GetBoolean("Debugging", Settings::HKeys::record_frame_times.c_str(), false); android_config->GetBoolean("Debugging", Settings::HKeys::record_frame_times.c_str(), false);
ReadSetting("Debugging", Settings::values.renderer_debug); ReadSetting("Debugging", Settings::values.renderer_debug);
ReadSetting("Debugging", Settings::values.pica_debugging);
ReadSetting("Debugging", Settings::values.use_gdbstub); ReadSetting("Debugging", Settings::values.use_gdbstub);
ReadSetting("Debugging", Settings::values.gdbstub_port); ReadSetting("Debugging", Settings::values.gdbstub_port);
ReadSetting("Debugging", Settings::values.instant_debug_log); ReadSetting("Debugging", Settings::values.instant_debug_log);

View File

@ -546,6 +546,10 @@ static const char* android_config_default_file_content = (BOOST_HANA_STRING(R"(
# 0 (default): Off, 1: On # 0 (default): Off, 1: On
)") DECLARE_KEY(renderer_debug) BOOST_HANA_STRING(R"( )") DECLARE_KEY(renderer_debug) BOOST_HANA_STRING(R"(
# Whether to enable PICA200 debugging (does nothing on Android)
# 0 (default): Off, 1: On
)") DECLARE_KEY(pica_debugging) BOOST_HANA_STRING(R"(
# Flush log output on every message # Flush log output on every message
# Immediately commits the debug log to file. Use this if Azahar crashes and the log output is being cut. # Immediately commits the debug log to file. Use this if Azahar crashes and the log output is being cut.
)") DECLARE_KEY(instant_debug_log) BOOST_HANA_STRING(R"( )") DECLARE_KEY(instant_debug_log) BOOST_HANA_STRING(R"(

View File

@ -255,7 +255,13 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
// Register microphone permission check // Register microphone permission check
system.RegisterMicPermissionCheck(&CheckMicPermission); system.RegisterMicPermissionCheck(&CheckMicPermission);
Pica::g_debug_context = Pica::DebugContext::Construct(); // No PICA debugging on Android
if (Settings::values.pica_debugging) {
Pica::g_debug_context = Pica::DebugContext::Construct();
} else {
Pica::g_debug_context.reset();
}
InputManager::Init(); InputManager::Init();
window->MakeCurrent(); window->MakeCurrent();

View File

@ -414,7 +414,11 @@ GMainWindow::GMainWindow(Core::System& system_)
LoadTranslation(); LoadTranslation();
Pica::g_debug_context = Pica::DebugContext::Construct(); if (Settings::values.pica_debugging) {
Pica::g_debug_context = Pica::DebugContext::Construct();
} else {
Pica::g_debug_context.reset();
}
setAcceptDrops(true); setAcceptDrops(true);
ui->setupUi(this); ui->setupUi(this);
statusBar()->hide(); statusBar()->hide();
@ -706,8 +710,12 @@ void GMainWindow::InitializeWidgets() {
} }
void GMainWindow::InitializeDebugWidgets() { void GMainWindow::InitializeDebugWidgets() {
connect(ui->action_Create_Pica_Surface_Viewer, &QAction::triggered, this, if (Pica::g_debug_context) {
&GMainWindow::OnCreateGraphicsSurfaceViewer); connect(ui->action_Create_Pica_Surface_Viewer, &QAction::triggered, this,
&GMainWindow::OnCreateGraphicsSurfaceViewer);
} else {
ui->action_Create_Pica_Surface_Viewer->setEnabled(false);
}
QMenu* debug_menu = ui->menu_View_Debugging; QMenu* debug_menu = ui->menu_View_Debugging;
@ -726,35 +734,37 @@ void GMainWindow::InitializeDebugWidgets() {
connect(this, &GMainWindow::EmulationStopping, registersWidget, connect(this, &GMainWindow::EmulationStopping, registersWidget,
&RegistersWidget::OnEmulationStopping); &RegistersWidget::OnEmulationStopping);
graphicsWidget = new GPUCommandStreamWidget(system, this); if (Pica::g_debug_context) {
addDockWidget(Qt::RightDockWidgetArea, graphicsWidget); graphicsWidget = new GPUCommandStreamWidget(system, this);
graphicsWidget->hide(); addDockWidget(Qt::RightDockWidgetArea, graphicsWidget);
debug_menu->addAction(graphicsWidget->toggleViewAction()); graphicsWidget->hide();
debug_menu->addAction(graphicsWidget->toggleViewAction());
graphicsCommandsWidget = new GPUCommandListWidget(system, this); graphicsCommandsWidget = new GPUCommandListWidget(system, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget); addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget);
graphicsCommandsWidget->hide(); graphicsCommandsWidget->hide();
debug_menu->addAction(graphicsCommandsWidget->toggleViewAction()); debug_menu->addAction(graphicsCommandsWidget->toggleViewAction());
graphicsBreakpointsWidget = new GraphicsBreakPointsWidget(Pica::g_debug_context, this); graphicsBreakpointsWidget = new GraphicsBreakPointsWidget(Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsBreakpointsWidget); addDockWidget(Qt::RightDockWidgetArea, graphicsBreakpointsWidget);
graphicsBreakpointsWidget->hide(); graphicsBreakpointsWidget->hide();
debug_menu->addAction(graphicsBreakpointsWidget->toggleViewAction()); debug_menu->addAction(graphicsBreakpointsWidget->toggleViewAction());
graphicsVertexShaderWidget = graphicsVertexShaderWidget =
new GraphicsVertexShaderWidget(system, Pica::g_debug_context, this); new GraphicsVertexShaderWidget(system, Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsVertexShaderWidget); addDockWidget(Qt::RightDockWidgetArea, graphicsVertexShaderWidget);
graphicsVertexShaderWidget->hide(); graphicsVertexShaderWidget->hide();
debug_menu->addAction(graphicsVertexShaderWidget->toggleViewAction()); debug_menu->addAction(graphicsVertexShaderWidget->toggleViewAction());
graphicsTracingWidget = new GraphicsTracingWidget(system, Pica::g_debug_context, this); graphicsTracingWidget = new GraphicsTracingWidget(system, Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsTracingWidget); addDockWidget(Qt::RightDockWidgetArea, graphicsTracingWidget);
graphicsTracingWidget->hide(); graphicsTracingWidget->hide();
debug_menu->addAction(graphicsTracingWidget->toggleViewAction()); debug_menu->addAction(graphicsTracingWidget->toggleViewAction());
connect(this, &GMainWindow::EmulationStarting, graphicsTracingWidget, connect(this, &GMainWindow::EmulationStarting, graphicsTracingWidget,
&GraphicsTracingWidget::OnEmulationStarting); &GraphicsTracingWidget::OnEmulationStarting);
connect(this, &GMainWindow::EmulationStopping, graphicsTracingWidget, connect(this, &GMainWindow::EmulationStopping, graphicsTracingWidget,
&GraphicsTracingWidget::OnEmulationStopping); &GraphicsTracingWidget::OnEmulationStopping);
}
waitTreeWidget = new WaitTreeWidget(system, this); waitTreeWidget = new WaitTreeWidget(system, this);
addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget); addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
@ -1553,7 +1563,7 @@ void GMainWindow::BootGame(const QString& filename) {
} }
// Register debug widgets // Register debug widgets
if (graphicsWidget->isVisible()) { if (graphicsWidget && graphicsWidget->isVisible()) {
graphicsWidget->Register(); graphicsWidget->Register();
} }
@ -1638,10 +1648,12 @@ void GMainWindow::ShutdownGame() {
// breakpoint after (or before) RequestStop() is called, the emulation would never be able // breakpoint after (or before) RequestStop() is called, the emulation would never be able
// to continue out to the main loop and terminate. Thus wait() would hang forever. // to continue out to the main loop and terminate. Thus wait() would hang forever.
// TODO(bunnei): This function is not thread safe, but it's being used as if it were // TODO(bunnei): This function is not thread safe, but it's being used as if it were
Pica::g_debug_context->ClearBreakpoints(); if (Pica::g_debug_context) {
Pica::g_debug_context->ClearBreakpoints();
}
// Unregister debug widgets // Unregister debug widgets
if (graphicsWidget->isVisible()) { if (graphicsWidget && graphicsWidget->isVisible()) {
graphicsWidget->Unregister(); graphicsWidget->Unregister();
} }

View File

@ -411,19 +411,19 @@ private:
std::vector<QString> physical_devices; std::vector<QString> physical_devices;
// Debugger panes // Debugger panes
ProfilerWidget* profilerWidget; ProfilerWidget* profilerWidget{};
#if MICROPROFILE_ENABLED #if MICROPROFILE_ENABLED
MicroProfileDialog* microProfileDialog; MicroProfileDialog* microProfileDialog{};
#endif #endif
RegistersWidget* registersWidget; RegistersWidget* registersWidget{};
GPUCommandStreamWidget* graphicsWidget; GPUCommandStreamWidget* graphicsWidget{};
GPUCommandListWidget* graphicsCommandsWidget; GPUCommandListWidget* graphicsCommandsWidget{};
GraphicsBreakPointsWidget* graphicsBreakpointsWidget; GraphicsBreakPointsWidget* graphicsBreakpointsWidget{};
GraphicsVertexShaderWidget* graphicsVertexShaderWidget; GraphicsVertexShaderWidget* graphicsVertexShaderWidget{};
GraphicsTracingWidget* graphicsTracingWidget; GraphicsTracingWidget* graphicsTracingWidget{};
IPCRecorderWidget* ipcRecorderWidget; IPCRecorderWidget* ipcRecorderWidget{};
LLEServiceModulesWidget* lleServiceModulesWidget; LLEServiceModulesWidget* lleServiceModulesWidget{};
WaitTreeWidget* waitTreeWidget; WaitTreeWidget* waitTreeWidget{};
QAction* actions_recent_files[max_recent_files_item]; QAction* actions_recent_files[max_recent_files_item];
std::array<QAction*, Core::SaveStateSlotCount> actions_load_state; std::array<QAction*, Core::SaveStateSlotCount> actions_load_state;

View File

@ -513,6 +513,7 @@ void QtConfig::ReadDebuggingValues() {
ReadBasicSetting(Settings::values.use_gdbstub); ReadBasicSetting(Settings::values.use_gdbstub);
ReadBasicSetting(Settings::values.gdbstub_port); ReadBasicSetting(Settings::values.gdbstub_port);
ReadBasicSetting(Settings::values.renderer_debug); ReadBasicSetting(Settings::values.renderer_debug);
ReadBasicSetting(Settings::values.pica_debugging);
ReadBasicSetting(Settings::values.dump_command_buffers); ReadBasicSetting(Settings::values.dump_command_buffers);
ReadBasicSetting(Settings::values.instant_debug_log); ReadBasicSetting(Settings::values.instant_debug_log);
ReadBasicSetting(Settings::values.enable_rpc_server); ReadBasicSetting(Settings::values.enable_rpc_server);
@ -1103,6 +1104,7 @@ void QtConfig::SaveDebuggingValues() {
WriteBasicSetting(Settings::values.use_gdbstub); WriteBasicSetting(Settings::values.use_gdbstub);
WriteBasicSetting(Settings::values.gdbstub_port); WriteBasicSetting(Settings::values.gdbstub_port);
WriteBasicSetting(Settings::values.renderer_debug); WriteBasicSetting(Settings::values.renderer_debug);
WriteBasicSetting(Settings::values.pica_debugging);
WriteBasicSetting(Settings::values.instant_debug_log); WriteBasicSetting(Settings::values.instant_debug_log);
WriteBasicSetting(Settings::values.enable_rpc_server); WriteBasicSetting(Settings::values.enable_rpc_server);
WriteBasicSetting(Settings::values.toggle_unique_data_console_type); WriteBasicSetting(Settings::values.toggle_unique_data_console_type);

View File

@ -82,8 +82,14 @@ ConfigureDebug::ConfigureDebug(bool is_powered_on_, QWidget* parent)
}); });
#endif #endif
connect(ui->toggle_pica_debugging, &QCheckBox::clicked, this, [this](bool checked) {
QMessageBox::information(this, tr("Relaunch Required"),
tr("Please relaunch Azahar for this setting to take effect."));
});
ui->toggle_cpu_jit->setEnabled(!is_powered_on); ui->toggle_cpu_jit->setEnabled(!is_powered_on);
ui->toggle_renderer_debug->setEnabled(!is_powered_on); ui->toggle_renderer_debug->setEnabled(!is_powered_on);
ui->toggle_pica_debugging->setEnabled(!is_powered_on);
ui->toggle_dump_command_buffers->setEnabled(!is_powered_on); ui->toggle_dump_command_buffers->setEnabled(!is_powered_on);
ui->enable_rpc_server->setEnabled(!is_powered_on); ui->enable_rpc_server->setEnabled(!is_powered_on);
ui->toggle_unique_data_console_type->setEnabled(!is_powered_on); ui->toggle_unique_data_console_type->setEnabled(!is_powered_on);
@ -135,6 +141,7 @@ void ConfigureDebug::SetConfiguration() {
Settings::values.break_on_unmapped_memory_access.GetValue()); Settings::values.break_on_unmapped_memory_access.GetValue());
ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug.GetValue()); ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug.GetValue());
ui->toggle_pica_debugging->setChecked(Settings::values.pica_debugging.GetValue());
ui->toggle_dump_command_buffers->setChecked(Settings::values.dump_command_buffers.GetValue()); ui->toggle_dump_command_buffers->setChecked(Settings::values.dump_command_buffers.GetValue());
if (!Settings::IsConfiguringGlobal()) { if (!Settings::IsConfiguringGlobal()) {
@ -181,6 +188,7 @@ void ConfigureDebug::ApplyConfiguration() {
Settings::values.break_on_unmapped_memory_access = Settings::values.break_on_unmapped_memory_access =
ui->break_on_unmapped_memory_access->isChecked(); ui->break_on_unmapped_memory_access->isChecked();
Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked(); Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked();
Settings::values.pica_debugging = ui->toggle_pica_debugging->isChecked();
Settings::values.dump_command_buffers = ui->toggle_dump_command_buffers->isChecked(); Settings::values.dump_command_buffers = ui->toggle_dump_command_buffers->isChecked();
Settings::values.instant_debug_log = ui->instant_debug_log->isChecked(); Settings::values.instant_debug_log = ui->instant_debug_log->isChecked();

View File

@ -250,7 +250,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="5" column="0">
<widget class="QCheckBox" name="toggle_pica_debugging">
<property name="text">
<string>Enable PICA200 debugging</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="toggle_dump_command_buffers"> <widget class="QCheckBox" name="toggle_dump_command_buffers">
<property name="text"> <property name="text">
<string>Dump command buffers</string> <string>Dump command buffers</string>

View File

@ -96,6 +96,7 @@ void LogSettings() {
log_setting("Renderer_SpirvShaderGen", values.spirv_shader_gen.GetValue()); log_setting("Renderer_SpirvShaderGen", values.spirv_shader_gen.GetValue());
log_setting("Renderer_DisableSpirvOptimizer", values.disable_spirv_optimizer.GetValue()); log_setting("Renderer_DisableSpirvOptimizer", values.disable_spirv_optimizer.GetValue());
log_setting("Renderer_Debug", values.renderer_debug.GetValue()); log_setting("Renderer_Debug", values.renderer_debug.GetValue());
log_setting("Renderer_PicaDebugging", values.pica_debugging.GetValue());
log_setting("Renderer_UseHwShader", values.use_hw_shader.GetValue()); log_setting("Renderer_UseHwShader", values.use_hw_shader.GetValue());
log_setting("Renderer_ShadersAccurateMul", values.shaders_accurate_mul.GetValue()); log_setting("Renderer_ShadersAccurateMul", values.shaders_accurate_mul.GetValue());
log_setting("Renderer_UseShaderJit", values.use_shader_jit.GetValue()); log_setting("Renderer_UseShaderJit", values.use_shader_jit.GetValue());

View File

@ -527,6 +527,7 @@ struct Values {
SwitchableSetting<u32> physical_device{0, Keys::physical_device}; SwitchableSetting<u32> physical_device{0, Keys::physical_device};
Setting<bool> use_gles{false, Keys::use_gles}; Setting<bool> use_gles{false, Keys::use_gles};
Setting<bool> renderer_debug{false, Keys::renderer_debug}; Setting<bool> renderer_debug{false, Keys::renderer_debug};
Setting<bool> pica_debugging{false, Keys::pica_debugging};
Setting<bool> dump_command_buffers{false, Keys::dump_command_buffers}; Setting<bool> dump_command_buffers{false, Keys::dump_command_buffers};
SwitchableSetting<bool> spirv_shader_gen{true, Keys::spirv_shader_gen}; SwitchableSetting<bool> spirv_shader_gen{true, Keys::spirv_shader_gen};
SwitchableSetting<bool> disable_spirv_optimizer{true, Keys::disable_spirv_optimizer}; SwitchableSetting<bool> disable_spirv_optimizer{true, Keys::disable_spirv_optimizer};

View File

@ -371,10 +371,6 @@ const Pica::PicaCore& GPU::PicaCore() const {
return impl->pica; return impl->pica;
} }
Pica::DebugContext& GPU::DebugContext() {
return *Pica::g_debug_context;
}
GraphicsDebugger& GPU::Debugger() { GraphicsDebugger& GPU::Debugger() {
return impl->gpu_debugger; return impl->gpu_debugger;
} }

View File

@ -84,9 +84,6 @@ public:
/// Returns an immutable reference to the PICA GPU. /// Returns an immutable reference to the PICA GPU.
[[nodiscard]] const Pica::PicaCore& PicaCore() const; [[nodiscard]] const Pica::PicaCore& PicaCore() const;
/// Returns a mutable reference to the pica debugging context.
[[nodiscard]] Pica::DebugContext& DebugContext();
/// Returns a mutable reference to the GSP command debugger. /// Returns a mutable reference to the GSP command debugger.
[[nodiscard]] GraphicsDebugger& Debugger(); [[nodiscard]] GraphicsDebugger& Debugger();