diff options
Diffstat (limited to '')
| -rw-r--r-- | src/citra/citra.cpp | 7 | ||||
| -rw-r--r-- | src/citra_qt/bootmanager.cpp | 5 | ||||
| -rw-r--r-- | src/citra_qt/debugger/profiler.cpp | 202 | ||||
| -rw-r--r-- | src/citra_qt/debugger/profiler.h | 17 | ||||
| -rw-r--r-- | src/citra_qt/main.cpp | 14 | ||||
| -rw-r--r-- | src/citra_qt/main.h | 2 | ||||
| -rw-r--r-- | src/common/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/common/microprofile.cpp | 7 | ||||
| -rw-r--r-- | src/common/microprofile.h | 25 | ||||
| -rw-r--r-- | src/common/microprofileui.h | 16 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/service/gsp_gpu.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 4 | ||||
| -rw-r--r-- | src/core/hw/gpu.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/command_processor.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/shader/shader.cpp | 3 |
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) : | |||
| 37 | void EmuThread::run() { | 38 | void 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 | ||
| 9 | using namespace Common::Profiling; | 21 | using 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 | |||
| 152 | class MicroProfileWidget : public QWidget { | ||
| 153 | public: | ||
| 154 | MicroProfileWidget(QWidget* parent = 0); | ||
| 155 | |||
| 156 | protected: | ||
| 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 | |||
| 169 | private: | ||
| 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 | |||
| 175 | MicroProfileDialog::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 | |||
| 197 | QAction* 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 | |||
| 208 | void MicroProfileDialog::showEvent(QShowEvent* ev) { | ||
| 209 | if (toggle_view_action) { | ||
| 210 | toggle_view_action->setChecked(isVisible()); | ||
| 211 | } | ||
| 212 | QWidget::showEvent(ev); | ||
| 213 | } | ||
| 214 | |||
| 215 | void 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. | ||
| 224 | static QPainter* mp_painter = nullptr; | ||
| 225 | |||
| 226 | MicroProfileWidget::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 | |||
| 236 | void 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 | |||
| 251 | void MicroProfileWidget::showEvent(QShowEvent* ev) { | ||
| 252 | update_timer.start(15); // ~60 Hz | ||
| 253 | QWidget::showEvent(ev); | ||
| 254 | } | ||
| 255 | |||
| 256 | void MicroProfileWidget::hideEvent(QHideEvent* ev) { | ||
| 257 | update_timer.stop(); | ||
| 258 | QWidget::hideEvent(ev); | ||
| 259 | } | ||
| 260 | |||
| 261 | void MicroProfileWidget::mouseMoveEvent(QMouseEvent* ev) { | ||
| 262 | MicroProfileMousePosition(ev->x(), ev->y(), 0); | ||
| 263 | ev->accept(); | ||
| 264 | } | ||
| 265 | |||
| 266 | void 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 | |||
| 272 | void 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 | |||
| 278 | void MicroProfileWidget::wheelEvent(QWheelEvent* ev) { | ||
| 279 | MicroProfileMousePosition(ev->x(), ev->y(), ev->delta() / 120); | ||
| 280 | ev->accept(); | ||
| 281 | } | ||
| 282 | |||
| 283 | void 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 | |||
| 291 | void 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 | |||
| 300 | void 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 | |||
| 315 | void 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 | |||
| 327 | void 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 | |||
| 52 | class MicroProfileDialog : public QWidget { | ||
| 53 | Q_OBJECT | ||
| 54 | |||
| 55 | public: | ||
| 56 | MicroProfileDialog(QWidget* parent = 0); | ||
| 57 | |||
| 58 | /// Returns a QAction that can be used to toggle visibility of this dialog. | ||
| 59 | QAction* toggleViewAction(); | ||
| 60 | |||
| 61 | protected: | ||
| 62 | void showEvent(QShowEvent* ev) override; | ||
| 63 | void hideEvent(QHideEvent* ev) override; | ||
| 64 | |||
| 65 | private: | ||
| 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; | |||
| 14 | class GRenderWindow; | 14 | class GRenderWindow; |
| 15 | class EmuThread; | 15 | class EmuThread; |
| 16 | class ProfilerWidget; | 16 | class ProfilerWidget; |
| 17 | class MicroProfileDialog; | ||
| 17 | class DisassemblerWidget; | 18 | class DisassemblerWidget; |
| 18 | class RegistersWidget; | 19 | class RegistersWidget; |
| 19 | class CallstackWidget; | 20 | class 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 | ||
| 3526 | MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64)); | ||
| 3527 | |||
| 3525 | static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { | 3528 | static 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 | ||
| 3595 | MICROPROFILE_DEFINE(DynCom_Execute, "DynCom", "Execute", MP_RGB(255, 0, 0)); | ||
| 3596 | |||
| 3591 | unsigned InterpreterMainLoop(ARMul_State* cpu) { | 3597 | unsigned 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 | ||
| 973 | MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); | ||
| 974 | |||
| 972 | void CallSVC(u32 immediate) { | 975 | void 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 | ||
| 89 | MICROPROFILE_DEFINE(GPU_DisplayTransfer, "GPU", "DisplayTransfer", MP_RGB(100, 100, 255)); | ||
| 90 | MICROPROFILE_DEFINE(GPU_CmdlistProcessing, "GPU", "Cmdlist Processing", MP_RGB(100, 255, 100)); | ||
| 91 | |||
| 88 | template <typename T> | 92 | template <typename T> |
| 89 | inline void Write(u32 addr, const T data) { | 93 | inline 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 | ||
| 47 | MICROPROFILE_DEFINE(GPU_Drawing, "GPU", "Drawing", MP_RGB(50, 50, 240)); | ||
| 48 | |||
| 46 | static void WritePicaReg(u32 id, u32 value, u32 mask) { | 49 | static 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 | ||
| 269 | static Common::Profiling::TimingCategory rasterization_category("Rasterization"); | 270 | static Common::Profiling::TimingCategory rasterization_category("Rasterization"); |
| 271 | MICROPROFILE_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 | ||
| 781 | MICROPROFILE_DEFINE(OpenGL_FramebufferReload, "OpenGL", "FB Reload", MP_RGB(70, 70, 200)); | ||
| 782 | |||
| 780 | void RasterizerOpenGL::ReloadColorBuffer() { | 783 | void 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 | ||
| 870 | Common::Profiling::TimingCategory buffer_commit_category("Framebuffer Commit"); | 877 | Common::Profiling::TimingCategory buffer_commit_category("Framebuffer Commit"); |
| 878 | MICROPROFILE_DEFINE(OpenGL_FramebufferCommit, "OpenGL", "FB Commit", MP_RGB(70, 70, 200)); | ||
| 871 | 879 | ||
| 872 | void RasterizerOpenGL::CommitColorBuffer() { | 880 | void 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 | ||
| 20 | MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); | ||
| 21 | |||
| 19 | void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) { | 22 | void 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 | ||
| 57 | static Common::Profiling::TimingCategory shader_category("Vertex Shader"); | 58 | static Common::Profiling::TimingCategory shader_category("Vertex Shader"); |
| 59 | MICROPROFILE_DEFINE(GPU_VertexShader, "GPU", "Vertex Shader", MP_RGB(50, 50, 240)); | ||
| 58 | 60 | ||
| 59 | OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attributes) { | 61 | OutputVertex 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; |