summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra/citra.cpp7
-rw-r--r--src/citra_qt/bootmanager.cpp5
-rw-r--r--src/citra_qt/debugger/profiler.cpp202
-rw-r--r--src/citra_qt/debugger/profiler.h17
-rw-r--r--src/citra_qt/main.cpp14
-rw-r--r--src/citra_qt/main.h2
-rw-r--r--src/common/CMakeLists.txt3
-rw-r--r--src/common/microprofile.cpp7
-rw-r--r--src/common/microprofile.h25
-rw-r--r--src/common/microprofileui.h16
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp7
-rw-r--r--src/core/hle/service/gsp_gpu.cpp5
-rw-r--r--src/core/hle/svc.cpp4
-rw-r--r--src/core/hw/gpu.cpp8
-rw-r--r--src/video_core/command_processor.cpp4
-rw-r--r--src/video_core/rasterizer.cpp3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp5
-rw-r--r--src/video_core/shader/shader.cpp3
19 files changed, 347 insertions, 0 deletions
diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp
index d6fcb66a5..46f4a07c9 100644
--- a/src/citra/citra.cpp
+++ b/src/citra/citra.cpp
@@ -6,6 +6,9 @@
6#include <thread> 6#include <thread>
7#include <iostream> 7#include <iostream>
8 8
9// This needs to be included before getopt.h because the latter #defines symbols used by it
10#include "common/microprofile.h"
11
9#ifdef _MSC_VER 12#ifdef _MSC_VER
10#include <getopt.h> 13#include <getopt.h>
11#else 14#else
@@ -59,6 +62,8 @@ int main(int argc, char **argv) {
59 Log::Filter log_filter(Log::Level::Debug); 62 Log::Filter log_filter(Log::Level::Debug);
60 Log::SetFilter(&log_filter); 63 Log::SetFilter(&log_filter);
61 64
65 MicroProfileOnThreadCreate("EmuThread");
66
62 if (boot_filename.empty()) { 67 if (boot_filename.empty()) {
63 LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); 68 LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
64 return -1; 69 return -1;
@@ -89,5 +94,7 @@ int main(int argc, char **argv) {
89 94
90 delete emu_window; 95 delete emu_window;
91 96
97 MicroProfileShutdown();
98
92 return 0; 99 return 0;
93} 100}
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index a96fbea5f..f8aacb527 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -14,6 +14,7 @@
14#include "common/string_util.h" 14#include "common/string_util.h"
15#include "common/scm_rev.h" 15#include "common/scm_rev.h"
16#include "common/key_map.h" 16#include "common/key_map.h"
17#include "common/microprofile.h"
17 18
18#include "core/core.h" 19#include "core/core.h"
19#include "core/settings.h" 20#include "core/settings.h"
@@ -37,6 +38,8 @@ EmuThread::EmuThread(GRenderWindow* render_window) :
37void EmuThread::run() { 38void EmuThread::run() {
38 render_window->MakeCurrent(); 39 render_window->MakeCurrent();
39 40
41 MicroProfileOnThreadCreate("EmuThread");
42
40 stop_run = false; 43 stop_run = false;
41 44
42 // holds whether the cpu was running during the last iteration, 45 // holds whether the cpu was running during the last iteration,
@@ -69,6 +72,8 @@ void EmuThread::run() {
69 } 72 }
70 } 73 }
71 74
75 MicroProfileOnThreadExit();
76
72 render_window->moveContext(); 77 render_window->moveContext();
73} 78}
74 79
diff --git a/src/citra_qt/debugger/profiler.cpp b/src/citra_qt/debugger/profiler.cpp
index 89b28c2f4..5261d4836 100644
--- a/src/citra_qt/debugger/profiler.cpp
+++ b/src/citra_qt/debugger/profiler.cpp
@@ -2,9 +2,21 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <QMouseEvent>
6#include <QPainter>
7#include <QString>
8
5#include "profiler.h" 9#include "profiler.h"
6 10
11#include "citra_qt/util/util.h"
12
7#include "common/profiler_reporting.h" 13#include "common/profiler_reporting.h"
14#include "common/microprofile.h"
15
16// Include the implementation of the UI in this file. This isn't in microprofile.cpp because the
17// non-Qt frontends don't need it (and don't implement the UI drawing hooks either).
18#define MICROPROFILEUI_IMPL 1
19#include "common/microprofileui.h"
8 20
9using namespace Common::Profiling; 21using namespace Common::Profiling;
10 22
@@ -136,3 +148,193 @@ void ProfilerWidget::setProfilingInfoUpdateEnabled(bool enable)
136 update_timer.stop(); 148 update_timer.stop();
137 } 149 }
138} 150}
151
152class MicroProfileWidget : public QWidget {
153public:
154 MicroProfileWidget(QWidget* parent = 0);
155
156protected:
157 void paintEvent(QPaintEvent* ev) override;
158 void showEvent(QShowEvent* ev) override;
159 void hideEvent(QHideEvent* ev) override;
160
161 void mouseMoveEvent(QMouseEvent* ev) override;
162 void mousePressEvent(QMouseEvent* ev) override;
163 void mouseReleaseEvent(QMouseEvent* ev) override;
164 void wheelEvent(QWheelEvent* ev) override;
165
166 void keyPressEvent(QKeyEvent* ev) override;
167 void keyReleaseEvent(QKeyEvent* ev) override;
168
169private:
170 /// This timer is used to redraw the widget's contents continuously. To save resources, it only
171 /// runs while the widget is visible.
172 QTimer update_timer;
173};
174
175MicroProfileDialog::MicroProfileDialog(QWidget* parent)
176 : QWidget(parent, Qt::Dialog)
177{
178 setObjectName("MicroProfile");
179 setWindowTitle(tr("MicroProfile"));
180 resize(1000, 600);
181 // Remove the "?" button from the titlebar and enable the maximize button
182 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::WindowMaximizeButtonHint);
183
184 MicroProfileWidget* widget = new MicroProfileWidget(this);
185
186 QLayout* layout = new QVBoxLayout(this);
187 layout->setContentsMargins(0, 0, 0, 0);
188 layout->addWidget(widget);
189 setLayout(layout);
190
191 // Configure focus so that widget is focusable and the dialog automatically forwards focus to it.
192 setFocusProxy(widget);
193 widget->setFocusPolicy(Qt::StrongFocus);
194 widget->setFocus();
195}
196
197QAction* MicroProfileDialog::toggleViewAction() {
198 if (toggle_view_action == nullptr) {
199 toggle_view_action = new QAction(windowTitle(), this);
200 toggle_view_action->setCheckable(true);
201 toggle_view_action->setChecked(isVisible());
202 connect(toggle_view_action, SIGNAL(toggled(bool)), SLOT(setVisible(bool)));
203 }
204
205 return toggle_view_action;
206}
207
208void MicroProfileDialog::showEvent(QShowEvent* ev) {
209 if (toggle_view_action) {
210 toggle_view_action->setChecked(isVisible());
211 }
212 QWidget::showEvent(ev);
213}
214
215void MicroProfileDialog::hideEvent(QHideEvent* ev) {
216 if (toggle_view_action) {
217 toggle_view_action->setChecked(isVisible());
218 }
219 QWidget::hideEvent(ev);
220}
221
222/// There's no way to pass a user pointer to MicroProfile, so this variable is used to make the
223/// QPainter available inside the drawing callbacks.
224static QPainter* mp_painter = nullptr;
225
226MicroProfileWidget::MicroProfileWidget(QWidget* parent) : QWidget(parent) {
227 // Send mouse motion events even when not dragging.
228 setMouseTracking(true);
229
230 MicroProfileSetDisplayMode(1); // Timers screen
231 MicroProfileInitUI();
232
233 connect(&update_timer, SIGNAL(timeout()), SLOT(update()));
234}
235
236void MicroProfileWidget::paintEvent(QPaintEvent* ev) {
237 QPainter painter(this);
238
239 painter.setBackground(Qt::black);
240 painter.eraseRect(rect());
241
242 QFont font = GetMonospaceFont();
243 font.setPixelSize(MICROPROFILE_TEXT_HEIGHT);
244 painter.setFont(font);
245
246 mp_painter = &painter;
247 MicroProfileDraw(rect().width(), rect().height());
248 mp_painter = nullptr;
249}
250
251void MicroProfileWidget::showEvent(QShowEvent* ev) {
252 update_timer.start(15); // ~60 Hz
253 QWidget::showEvent(ev);
254}
255
256void MicroProfileWidget::hideEvent(QHideEvent* ev) {
257 update_timer.stop();
258 QWidget::hideEvent(ev);
259}
260
261void MicroProfileWidget::mouseMoveEvent(QMouseEvent* ev) {
262 MicroProfileMousePosition(ev->x(), ev->y(), 0);
263 ev->accept();
264}
265
266void MicroProfileWidget::mousePressEvent(QMouseEvent* ev) {
267 MicroProfileMousePosition(ev->x(), ev->y(), 0);
268 MicroProfileMouseButton(ev->buttons() & Qt::LeftButton, ev->buttons() & Qt::RightButton);
269 ev->accept();
270}
271
272void MicroProfileWidget::mouseReleaseEvent(QMouseEvent* ev) {
273 MicroProfileMousePosition(ev->x(), ev->y(), 0);
274 MicroProfileMouseButton(ev->buttons() & Qt::LeftButton, ev->buttons() & Qt::RightButton);
275 ev->accept();
276}
277
278void MicroProfileWidget::wheelEvent(QWheelEvent* ev) {
279 MicroProfileMousePosition(ev->x(), ev->y(), ev->delta() / 120);
280 ev->accept();
281}
282
283void MicroProfileWidget::keyPressEvent(QKeyEvent* ev) {
284 if (ev->key() == Qt::Key_Control) {
285 // Inform MicroProfile that the user is holding Ctrl.
286 MicroProfileModKey(1);
287 }
288 QWidget::keyPressEvent(ev);
289}
290
291void MicroProfileWidget::keyReleaseEvent(QKeyEvent* ev) {
292 if (ev->key() == Qt::Key_Control) {
293 MicroProfileModKey(0);
294 }
295 QWidget::keyReleaseEvent(ev);
296}
297
298// These functions are called by MicroProfileDraw to draw the interface elements on the screen.
299
300void MicroProfileDrawText(int x, int y, u32 hex_color, const char* text, u32 text_length) {
301 // hex_color does not include an alpha, so it must be assumed to be 255
302 mp_painter->setPen(QColor::fromRgb(hex_color));
303
304 // It's impossible to draw a string using a monospaced font with a fixed width per cell in a
305 // way that's reliable across different platforms and fonts as far as I (yuriks) can tell, so
306 // draw each character individually in order to precisely control the text advance.
307 for (u32 i = 0; i < text_length; ++i) {
308 // Position the text baseline 1 pixel above the bottom of the text cell, this gives nice
309 // vertical alignment of text for a wide range of tested fonts.
310 mp_painter->drawText(x, y + MICROPROFILE_TEXT_HEIGHT - 2, QChar(text[i]));
311 x += MICROPROFILE_TEXT_WIDTH + 1;
312 }
313}
314
315void MicroProfileDrawBox(int left, int top, int right, int bottom, u32 hex_color, MicroProfileBoxType type) {
316 QColor color = QColor::fromRgba(hex_color);
317 QBrush brush = color;
318 if (type == MicroProfileBoxTypeBar) {
319 QLinearGradient gradient(left, top, left, bottom);
320 gradient.setColorAt(0.f, color.lighter(125));
321 gradient.setColorAt(1.f, color.darker(125));
322 brush = gradient;
323 }
324 mp_painter->fillRect(left, top, right - left, bottom - top, brush);
325}
326
327void MicroProfileDrawLine2D(u32 vertices_length, float* vertices, u32 hex_color) {
328 // Temporary vector used to convert between the float array and QPointF. Marked static to reuse
329 // the allocation across calls.
330 static std::vector<QPointF> point_buf;
331
332 for (u32 i = 0; i < vertices_length; ++i) {
333 point_buf.emplace_back(vertices[i*2 + 0], vertices[i*2 + 1]);
334 }
335
336 // hex_color does not include an alpha, so it must be assumed to be 255
337 mp_painter->setPen(QColor::fromRgb(hex_color));
338 mp_painter->drawPolyline(point_buf.data(), vertices_length);
339 point_buf.clear();
340}
diff --git a/src/citra_qt/debugger/profiler.h b/src/citra_qt/debugger/profiler.h
index fabf279b8..2199eaef1 100644
--- a/src/citra_qt/debugger/profiler.h
+++ b/src/citra_qt/debugger/profiler.h
@@ -48,3 +48,20 @@ private:
48 48
49 QTimer update_timer; 49 QTimer update_timer;
50}; 50};
51
52class MicroProfileDialog : public QWidget {
53 Q_OBJECT
54
55public:
56 MicroProfileDialog(QWidget* parent = 0);
57
58 /// Returns a QAction that can be used to toggle visibility of this dialog.
59 QAction* toggleViewAction();
60
61protected:
62 void showEvent(QShowEvent* ev) override;
63 void hideEvent(QHideEvent* ev) override;
64
65private:
66 QAction* toggle_view_action = nullptr;
67};
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 8bf2a3e13..7fb1b0dcb 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -17,6 +17,7 @@
17#include "common/logging/backend.h" 17#include "common/logging/backend.h"
18#include "common/logging/filter.h" 18#include "common/logging/filter.h"
19#include "common/make_unique.h" 19#include "common/make_unique.h"
20#include "common/microprofile.h"
20#include "common/platform.h" 21#include "common/platform.h"
21#include "common/scm_rev.h" 22#include "common/scm_rev.h"
22#include "common/scope_exit.h" 23#include "common/scope_exit.h"
@@ -64,6 +65,9 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
64 addDockWidget(Qt::BottomDockWidgetArea, profilerWidget); 65 addDockWidget(Qt::BottomDockWidgetArea, profilerWidget);
65 profilerWidget->hide(); 66 profilerWidget->hide();
66 67
68 microProfileDialog = new MicroProfileDialog(this);
69 microProfileDialog->hide();
70
67 disasmWidget = new DisassemblerWidget(this, emu_thread.get()); 71 disasmWidget = new DisassemblerWidget(this, emu_thread.get());
68 addDockWidget(Qt::BottomDockWidgetArea, disasmWidget); 72 addDockWidget(Qt::BottomDockWidgetArea, disasmWidget);
69 disasmWidget->hide(); 73 disasmWidget->hide();
@@ -102,6 +106,7 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
102 106
103 QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging")); 107 QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging"));
104 debug_menu->addAction(profilerWidget->toggleViewAction()); 108 debug_menu->addAction(profilerWidget->toggleViewAction());
109 debug_menu->addAction(microProfileDialog->toggleViewAction());
105 debug_menu->addAction(disasmWidget->toggleViewAction()); 110 debug_menu->addAction(disasmWidget->toggleViewAction());
106 debug_menu->addAction(registersWidget->toggleViewAction()); 111 debug_menu->addAction(registersWidget->toggleViewAction());
107 debug_menu->addAction(callstackWidget->toggleViewAction()); 112 debug_menu->addAction(callstackWidget->toggleViewAction());
@@ -128,6 +133,8 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
128 restoreGeometry(settings.value("geometry").toByteArray()); 133 restoreGeometry(settings.value("geometry").toByteArray());
129 restoreState(settings.value("state").toByteArray()); 134 restoreState(settings.value("state").toByteArray());
130 render_window->restoreGeometry(settings.value("geometryRenderWindow").toByteArray()); 135 render_window->restoreGeometry(settings.value("geometryRenderWindow").toByteArray());
136 microProfileDialog->restoreGeometry(settings.value("microProfileDialogGeometry").toByteArray());
137 microProfileDialog->setVisible(settings.value("microProfileDialogVisible").toBool());
131 138
132 ui.action_Use_Hardware_Renderer->setChecked(Settings::values.use_hw_renderer); 139 ui.action_Use_Hardware_Renderer->setChecked(Settings::values.use_hw_renderer);
133 SetHardwareRendererEnabled(ui.action_Use_Hardware_Renderer->isChecked()); 140 SetHardwareRendererEnabled(ui.action_Use_Hardware_Renderer->isChecked());
@@ -434,6 +441,8 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
434 settings.setValue("geometry", saveGeometry()); 441 settings.setValue("geometry", saveGeometry());
435 settings.setValue("state", saveState()); 442 settings.setValue("state", saveState());
436 settings.setValue("geometryRenderWindow", render_window->saveGeometry()); 443 settings.setValue("geometryRenderWindow", render_window->saveGeometry());
444 settings.setValue("microProfileDialogGeometry", microProfileDialog->saveGeometry());
445 settings.setValue("microProfileDialogVisible", microProfileDialog->isVisible());
437 settings.setValue("singleWindowMode", ui.action_Single_Window_Mode->isChecked()); 446 settings.setValue("singleWindowMode", ui.action_Single_Window_Mode->isChecked());
438 settings.setValue("displayTitleBars", ui.actionDisplay_widget_title_bars->isChecked()); 447 settings.setValue("displayTitleBars", ui.actionDisplay_widget_title_bars->isChecked());
439 settings.setValue("firstStart", false); 448 settings.setValue("firstStart", false);
@@ -456,6 +465,11 @@ int main(int argc, char* argv[]) {
456 Log::Filter log_filter(Log::Level::Info); 465 Log::Filter log_filter(Log::Level::Info);
457 Log::SetFilter(&log_filter); 466 Log::SetFilter(&log_filter);
458 467
468 MicroProfileOnThreadCreate("Frontend");
469 SCOPE_EXIT({
470 MicroProfileShutdown();
471 });
472
459 // Init settings params 473 // Init settings params
460 QSettings::setDefaultFormat(QSettings::IniFormat); 474 QSettings::setDefaultFormat(QSettings::IniFormat);
461 QCoreApplication::setOrganizationName("Citra team"); 475 QCoreApplication::setOrganizationName("Citra team");
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index 6f1292295..32523fded 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -14,6 +14,7 @@ class GImageInfo;
14class GRenderWindow; 14class GRenderWindow;
15class EmuThread; 15class EmuThread;
16class ProfilerWidget; 16class ProfilerWidget;
17class MicroProfileDialog;
17class DisassemblerWidget; 18class DisassemblerWidget;
18class RegistersWidget; 19class RegistersWidget;
19class CallstackWidget; 20class CallstackWidget;
@@ -104,6 +105,7 @@ private:
104 std::unique_ptr<EmuThread> emu_thread; 105 std::unique_ptr<EmuThread> emu_thread;
105 106
106 ProfilerWidget* profilerWidget; 107 ProfilerWidget* profilerWidget;
108 MicroProfileDialog* microProfileDialog;
107 DisassemblerWidget* disasmWidget; 109 DisassemblerWidget* disasmWidget;
108 RegistersWidget* registersWidget; 110 RegistersWidget* registersWidget;
109 CallstackWidget* callstackWidget; 111 CallstackWidget* callstackWidget;
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index e743a026d..7f3712efa 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -11,6 +11,7 @@ set(SRCS
11 logging/text_formatter.cpp 11 logging/text_formatter.cpp
12 logging/backend.cpp 12 logging/backend.cpp
13 memory_util.cpp 13 memory_util.cpp
14 microprofile.cpp
14 misc.cpp 15 misc.cpp
15 profiler.cpp 16 profiler.cpp
16 scm_rev.cpp 17 scm_rev.cpp
@@ -43,6 +44,8 @@ set(HEADERS
43 make_unique.h 44 make_unique.h
44 math_util.h 45 math_util.h
45 memory_util.h 46 memory_util.h
47 microprofile.h
48 microprofileui.h
46 platform.h 49 platform.h
47 profiler.h 50 profiler.h
48 profiler_reporting.h 51 profiler_reporting.h
diff --git a/src/common/microprofile.cpp b/src/common/microprofile.cpp
new file mode 100644
index 000000000..ee25dd37f
--- /dev/null
+++ b/src/common/microprofile.cpp
@@ -0,0 +1,7 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5// Includes the MicroProfile implementation in this file for compilation
6#define MICROPROFILE_IMPL 1
7#include "common/microprofile.h"
diff --git a/src/common/microprofile.h b/src/common/microprofile.h
new file mode 100644
index 000000000..9eb6016a8
--- /dev/null
+++ b/src/common/microprofile.h
@@ -0,0 +1,25 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7// Customized Citra settings.
8// This file wraps the MicroProfile header so that these are consistent everywhere.
9#define MICROPROFILE_WEBSERVER 0
10#define MICROPROFILE_GPU_TIMERS 0 // TODO: Implement timer queries when we upgrade to OpenGL 3.3
11#define MICROPROFILE_CONTEXT_SWITCH_TRACE 0
12#define MICROPROFILE_PER_THREAD_BUFFER_SIZE (2048<<12) // 8 MB
13
14#include <microprofile.h>
15
16#define MP_RGB(r, g, b) ((r) << 16 | (g) << 8 | (b) << 0)
17
18// On OS X, some Mach header included by MicroProfile defines these as macros, conflicting with
19// identifiers we use.
20#ifdef PAGE_SIZE
21#undef PAGE_SIZE
22#endif
23#ifdef PAGE_MASK
24#undef PAGE_MASK
25#endif
diff --git a/src/common/microprofileui.h b/src/common/microprofileui.h
new file mode 100644
index 000000000..97c369bd9
--- /dev/null
+++ b/src/common/microprofileui.h
@@ -0,0 +1,16 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/microprofile.h"
8
9// Customized Citra settings.
10// This file wraps the MicroProfile header so that these are consistent everywhere.
11#define MICROPROFILE_TEXT_WIDTH 6
12#define MICROPROFILE_TEXT_HEIGHT 12
13#define MICROPROFILE_HELP_ALT "Right-Click"
14#define MICROPROFILE_HELP_MOD "Ctrl"
15
16#include <microprofileui.h>
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 422e80b50..01c712f24 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -9,6 +9,7 @@
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "common/microprofile.h"
12#include "common/profiler.h" 13#include "common/profiler.h"
13 14
14#include "core/memory.h" 15#include "core/memory.h"
@@ -3522,8 +3523,11 @@ enum {
3522 FETCH_EXCEPTION 3523 FETCH_EXCEPTION
3523}; 3524};
3524 3525
3526MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64));
3527
3525static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { 3528static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
3526 Common::Profiling::ScopeTimer timer_decode(profile_decode); 3529 Common::Profiling::ScopeTimer timer_decode(profile_decode);
3530 MICROPROFILE_SCOPE(DynCom_Decode);
3527 3531
3528 // Decode instruction, get index 3532 // Decode instruction, get index
3529 // Allocate memory and init InsCream 3533 // Allocate memory and init InsCream
@@ -3588,8 +3592,11 @@ static int clz(unsigned int x) {
3588 return n; 3592 return n;
3589} 3593}
3590 3594
3595MICROPROFILE_DEFINE(DynCom_Execute, "DynCom", "Execute", MP_RGB(255, 0, 0));
3596
3591unsigned InterpreterMainLoop(ARMul_State* cpu) { 3597unsigned InterpreterMainLoop(ARMul_State* cpu) {
3592 Common::Profiling::ScopeTimer timer_execute(profile_execute); 3598 Common::Profiling::ScopeTimer timer_execute(profile_execute);
3599 MICROPROFILE_SCOPE(DynCom_Execute);
3593 3600
3594 #undef RM 3601 #undef RM
3595 #undef RS 3602 #undef RS
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index fde508a13..c3d0d28a5 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/bit_field.h" 5#include "common/bit_field.h"
6#include "common/microprofile.h"
6 7
7#include "core/memory.h" 8#include "core/memory.h"
8#include "core/hle/kernel/event.h" 9#include "core/hle/kernel/event.h"
@@ -229,6 +230,10 @@ void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
229 230
230 if (Pica::g_debug_context) 231 if (Pica::g_debug_context)
231 Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr); 232 Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr);
233
234 if (screen_id == 0) {
235 MicroProfileFlip();
236 }
232} 237}
233 238
234/** 239/**
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 89ac45a6f..19f750d72 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -5,6 +5,7 @@
5#include <map> 5#include <map>
6 6
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/microprofile.h"
8#include "common/profiler.h" 9#include "common/profiler.h"
9#include "common/string_util.h" 10#include "common/string_util.h"
10#include "common/symbols.h" 11#include "common/symbols.h"
@@ -969,8 +970,11 @@ static const FunctionDef* GetSVCInfo(u32 func_num) {
969 return &SVC_Table[func_num]; 970 return &SVC_Table[func_num];
970} 971}
971 972
973MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
974
972void CallSVC(u32 immediate) { 975void CallSVC(u32 immediate) {
973 Common::Profiling::ScopeTimer timer_svc(profiler_svc); 976 Common::Profiling::ScopeTimer timer_svc(profiler_svc);
977 MICROPROFILE_SCOPE(Kernel_SVC);
974 978
975 const FunctionDef* info = GetSVCInfo(immediate); 979 const FunctionDef* info = GetSVCInfo(immediate);
976 if (info) { 980 if (info) {
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 68ae38289..bc7bde903 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -9,6 +9,7 @@
9#include "common/color.h" 9#include "common/color.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "common/microprofile.h"
12#include "common/vector_math.h" 13#include "common/vector_math.h"
13 14
14#include "core/settings.h" 15#include "core/settings.h"
@@ -85,6 +86,9 @@ static Math::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_
85 } 86 }
86} 87}
87 88
89MICROPROFILE_DEFINE(GPU_DisplayTransfer, "GPU", "DisplayTransfer", MP_RGB(100, 100, 255));
90MICROPROFILE_DEFINE(GPU_CmdlistProcessing, "GPU", "Cmdlist Processing", MP_RGB(100, 255, 100));
91
88template <typename T> 92template <typename T>
89inline void Write(u32 addr, const T data) { 93inline void Write(u32 addr, const T data) {
90 addr -= HW::VADDR_GPU; 94 addr -= HW::VADDR_GPU;
@@ -150,6 +154,8 @@ inline void Write(u32 addr, const T data) {
150 154
151 case GPU_REG_INDEX(display_transfer_config.trigger): 155 case GPU_REG_INDEX(display_transfer_config.trigger):
152 { 156 {
157 MICROPROFILE_SCOPE(GPU_DisplayTransfer);
158
153 const auto& config = g_regs.display_transfer_config; 159 const auto& config = g_regs.display_transfer_config;
154 if (config.trigger & 1) { 160 if (config.trigger & 1) {
155 161
@@ -344,6 +350,8 @@ inline void Write(u32 addr, const T data) {
344 const auto& config = g_regs.command_processor_config; 350 const auto& config = g_regs.command_processor_config;
345 if (config.trigger & 1) 351 if (config.trigger & 1)
346 { 352 {
353 MICROPROFILE_SCOPE(GPU_CmdlistProcessing);
354
347 u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress()); 355 u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress());
348 356
349 if (Pica::g_debug_context && Pica::g_debug_context->recorder) { 357 if (Pica::g_debug_context && Pica::g_debug_context->recorder) {
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index d82e20f86..a78985510 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -4,6 +4,7 @@
4 4
5#include <boost/range/algorithm/fill.hpp> 5#include <boost/range/algorithm/fill.hpp>
6 6
7#include "common/microprofile.h"
7#include "common/profiler.h" 8#include "common/profiler.h"
8 9
9#include "core/hle/service/gsp_gpu.h" 10#include "core/hle/service/gsp_gpu.h"
@@ -43,6 +44,8 @@ static const u32 expand_bits_to_bytes[] = {
43 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff 44 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
44}; 45};
45 46
47MICROPROFILE_DEFINE(GPU_Drawing, "GPU", "Drawing", MP_RGB(50, 50, 240));
48
46static void WritePicaReg(u32 id, u32 value, u32 mask) { 49static void WritePicaReg(u32 id, u32 value, u32 mask) {
47 auto& regs = g_state.regs; 50 auto& regs = g_state.regs;
48 51
@@ -126,6 +129,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
126 case PICA_REG_INDEX(trigger_draw_indexed): 129 case PICA_REG_INDEX(trigger_draw_indexed):
127 { 130 {
128 Common::Profiling::ScopeTimer scope_timer(category_drawing); 131 Common::Profiling::ScopeTimer scope_timer(category_drawing);
132 MICROPROFILE_SCOPE(GPU_Drawing);
129 133
130#if PICA_LOG_TEV 134#if PICA_LOG_TEV
131 DebugUtils::DumpTevStageConfig(regs.GetTevStages()); 135 DebugUtils::DumpTevStageConfig(regs.GetTevStages());
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index b83798b0f..4a159da8e 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -7,6 +7,7 @@
7#include "common/color.h" 7#include "common/color.h"
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "common/math_util.h" 9#include "common/math_util.h"
10#include "common/microprofile.h"
10#include "common/profiler.h" 11#include "common/profiler.h"
11 12
12#include "core/hw/gpu.h" 13#include "core/hw/gpu.h"
@@ -267,6 +268,7 @@ static int SignedArea (const Math::Vec2<Fix12P4>& vtx1,
267}; 268};
268 269
269static Common::Profiling::TimingCategory rasterization_category("Rasterization"); 270static Common::Profiling::TimingCategory rasterization_category("Rasterization");
271MICROPROFILE_DEFINE(GPU_Rasterization, "GPU", "Rasterization", MP_RGB(50, 50, 240));
270 272
271/** 273/**
272 * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing 274 * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing
@@ -279,6 +281,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
279{ 281{
280 const auto& regs = g_state.regs; 282 const auto& regs = g_state.regs;
281 Common::Profiling::ScopeTimer timer(rasterization_category); 283 Common::Profiling::ScopeTimer timer(rasterization_category);
284 MICROPROFILE_SCOPE(GPU_Rasterization);
282 285
283 // vertex positions in rasterizer coordinates 286 // vertex positions in rasterizer coordinates
284 static auto FloatToFix = [](float24 flt) { 287 static auto FloatToFix = [](float24 flt) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 9f1552adf..deb9971bb 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -7,6 +7,7 @@
7 7
8#include "common/color.h" 8#include "common/color.h"
9#include "common/math_util.h" 9#include "common/math_util.h"
10#include "common/microprofile.h"
10#include "common/profiler.h" 11#include "common/profiler.h"
11 12
12#include "core/hw/gpu.h" 13#include "core/hw/gpu.h"
@@ -777,12 +778,16 @@ void RasterizerOpenGL::SyncDrawState() {
777 state.Apply(); 778 state.Apply();
778} 779}
779 780
781MICROPROFILE_DEFINE(OpenGL_FramebufferReload, "OpenGL", "FB Reload", MP_RGB(70, 70, 200));
782
780void RasterizerOpenGL::ReloadColorBuffer() { 783void RasterizerOpenGL::ReloadColorBuffer() {
781 u8* color_buffer = Memory::GetPhysicalPointer(Pica::g_state.regs.framebuffer.GetColorBufferPhysicalAddress()); 784 u8* color_buffer = Memory::GetPhysicalPointer(Pica::g_state.regs.framebuffer.GetColorBufferPhysicalAddress());
782 785
783 if (color_buffer == nullptr) 786 if (color_buffer == nullptr)
784 return; 787 return;
785 788
789 MICROPROFILE_SCOPE(OpenGL_FramebufferReload);
790
786 u32 bytes_per_pixel = Pica::Regs::BytesPerColorPixel(fb_color_texture.format); 791 u32 bytes_per_pixel = Pica::Regs::BytesPerColorPixel(fb_color_texture.format);
787 792
788 std::unique_ptr<u8[]> temp_fb_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]); 793 std::unique_ptr<u8[]> temp_fb_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]);
@@ -822,6 +827,8 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
822 if (depth_buffer == nullptr) 827 if (depth_buffer == nullptr)
823 return; 828 return;
824 829
830 MICROPROFILE_SCOPE(OpenGL_FramebufferReload);
831
825 u32 bytes_per_pixel = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format); 832 u32 bytes_per_pixel = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format);
826 833
827 // OpenGL needs 4 bpp alignment for D24 834 // OpenGL needs 4 bpp alignment for D24
@@ -868,6 +875,7 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
868} 875}
869 876
870Common::Profiling::TimingCategory buffer_commit_category("Framebuffer Commit"); 877Common::Profiling::TimingCategory buffer_commit_category("Framebuffer Commit");
878MICROPROFILE_DEFINE(OpenGL_FramebufferCommit, "OpenGL", "FB Commit", MP_RGB(70, 70, 200));
871 879
872void RasterizerOpenGL::CommitColorBuffer() { 880void RasterizerOpenGL::CommitColorBuffer() {
873 if (last_fb_color_addr != 0) { 881 if (last_fb_color_addr != 0) {
@@ -875,6 +883,7 @@ void RasterizerOpenGL::CommitColorBuffer() {
875 883
876 if (color_buffer != nullptr) { 884 if (color_buffer != nullptr) {
877 Common::Profiling::ScopeTimer timer(buffer_commit_category); 885 Common::Profiling::ScopeTimer timer(buffer_commit_category);
886 MICROPROFILE_SCOPE(OpenGL_FramebufferCommit);
878 887
879 u32 bytes_per_pixel = Pica::Regs::BytesPerColorPixel(fb_color_texture.format); 888 u32 bytes_per_pixel = Pica::Regs::BytesPerColorPixel(fb_color_texture.format);
880 889
@@ -911,6 +920,7 @@ void RasterizerOpenGL::CommitDepthBuffer() {
911 920
912 if (depth_buffer != nullptr) { 921 if (depth_buffer != nullptr) {
913 Common::Profiling::ScopeTimer timer(buffer_commit_category); 922 Common::Profiling::ScopeTimer timer(buffer_commit_category);
923 MICROPROFILE_SCOPE(OpenGL_FramebufferCommit);
914 924
915 u32 bytes_per_pixel = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format); 925 u32 bytes_per_pixel = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format);
916 926
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 70f0ba5f1..e4247051c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -4,6 +4,7 @@
4 4
5#include "common/make_unique.h" 5#include "common/make_unique.h"
6#include "common/math_util.h" 6#include "common/math_util.h"
7#include "common/microprofile.h"
7#include "common/vector_math.h" 8#include "common/vector_math.h"
8 9
9#include "core/memory.h" 10#include "core/memory.h"
@@ -16,6 +17,8 @@ RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
16 FullFlush(); 17 FullFlush();
17} 18}
18 19
20MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192));
21
19void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) { 22void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) {
20 PAddr texture_addr = config.config.GetPhysicalAddress(); 23 PAddr texture_addr = config.config.GetPhysicalAddress();
21 24
@@ -25,6 +28,8 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text
25 state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.handle; 28 state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.handle;
26 state.Apply(); 29 state.Apply();
27 } else { 30 } else {
31 MICROPROFILE_SCOPE(OpenGL_TextureUpload);
32
28 std::unique_ptr<CachedTexture> new_texture = Common::make_unique<CachedTexture>(); 33 std::unique_ptr<CachedTexture> new_texture = Common::make_unique<CachedTexture>();
29 34
30 new_texture->texture.Create(); 35 new_texture->texture.Create();
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 4e9836c80..be5588c00 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -9,6 +9,7 @@
9 9
10#include "common/hash.h" 10#include "common/hash.h"
11#include "common/make_unique.h" 11#include "common/make_unique.h"
12#include "common/microprofile.h"
12#include "common/profiler.h" 13#include "common/profiler.h"
13 14
14#include "video_core/debug_utils/debug_utils.h" 15#include "video_core/debug_utils/debug_utils.h"
@@ -55,11 +56,13 @@ void Shutdown() {
55} 56}
56 57
57static Common::Profiling::TimingCategory shader_category("Vertex Shader"); 58static Common::Profiling::TimingCategory shader_category("Vertex Shader");
59MICROPROFILE_DEFINE(GPU_VertexShader, "GPU", "Vertex Shader", MP_RGB(50, 50, 240));
58 60
59OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attributes) { 61OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attributes) {
60 auto& config = g_state.regs.vs; 62 auto& config = g_state.regs.vs;
61 63
62 Common::Profiling::ScopeTimer timer(shader_category); 64 Common::Profiling::ScopeTimer timer(shader_category);
65 MICROPROFILE_SCOPE(GPU_VertexShader);
63 66
64 state.program_counter = config.main_offset; 67 state.program_counter = config.main_offset;
65 state.debug.max_offset = 0; 68 state.debug.max_offset = 0;