diff options
| author | 2014-08-14 19:21:55 +0200 | |
|---|---|---|
| committer | 2014-08-25 22:03:18 +0200 | |
| commit | 26ade98411c1d76540695f15378ff7f6b5388b1a (patch) | |
| tree | db1b6eba40bacdc049d4c3c668ee875b209c73ac /src/citra_qt/debugger/graphics_cmdlists.cpp | |
| parent | Pica/CommandProcessor: Implement parameter masking. (diff) | |
| download | yuzu-26ade98411c1d76540695f15378ff7f6b5388b1a.tar.gz yuzu-26ade98411c1d76540695f15378ff7f6b5388b1a.tar.xz yuzu-26ade98411c1d76540695f15378ff7f6b5388b1a.zip | |
Pica/citra-qt: Replace command list view and command list debugging code with something more sophisticated.
Diffstat (limited to 'src/citra_qt/debugger/graphics_cmdlists.cpp')
| -rw-r--r-- | src/citra_qt/debugger/graphics_cmdlists.cpp | 144 |
1 files changed, 50 insertions, 94 deletions
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp index e98560a19..71dd166cd 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics_cmdlists.cpp | |||
| @@ -2,53 +2,21 @@ | |||
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "graphics_cmdlists.hxx" | 5 | #include <QListView> |
| 6 | #include <QPushButton> | ||
| 7 | #include <QVBoxLayout> | ||
| 6 | #include <QTreeView> | 8 | #include <QTreeView> |
| 7 | 9 | ||
| 8 | extern GraphicsDebugger g_debugger; | 10 | #include "graphics_cmdlists.hxx" |
| 9 | |||
| 10 | GPUCommandListModel::GPUCommandListModel(QObject* parent) : QAbstractItemModel(parent) | ||
| 11 | { | ||
| 12 | root_item = new TreeItem(TreeItem::ROOT, 0, NULL, this); | ||
| 13 | |||
| 14 | connect(this, SIGNAL(CommandListCalled()), this, SLOT(OnCommandListCalledInternal()), Qt::UniqueConnection); | ||
| 15 | } | ||
| 16 | |||
| 17 | QModelIndex GPUCommandListModel::index(int row, int column, const QModelIndex& parent) const | ||
| 18 | { | ||
| 19 | TreeItem* item; | ||
| 20 | |||
| 21 | if (!parent.isValid()) { | ||
| 22 | item = root_item; | ||
| 23 | } else { | ||
| 24 | item = (TreeItem*)parent.internalPointer(); | ||
| 25 | } | ||
| 26 | |||
| 27 | return createIndex(row, column, item->children[row]); | ||
| 28 | } | ||
| 29 | 11 | ||
| 30 | QModelIndex GPUCommandListModel::parent(const QModelIndex& child) const | 12 | GPUCommandListModel::GPUCommandListModel(QObject* parent) : QAbstractListModel(parent) |
| 31 | { | 13 | { |
| 32 | if (!child.isValid()) | ||
| 33 | return QModelIndex(); | ||
| 34 | |||
| 35 | TreeItem* item = (TreeItem*)child.internalPointer(); | ||
| 36 | |||
| 37 | if (item->parent == NULL) | ||
| 38 | return QModelIndex(); | ||
| 39 | 14 | ||
| 40 | return createIndex(item->parent->index, 0, item->parent); | ||
| 41 | } | 15 | } |
| 42 | 16 | ||
| 43 | int GPUCommandListModel::rowCount(const QModelIndex& parent) const | 17 | int GPUCommandListModel::rowCount(const QModelIndex& parent) const |
| 44 | { | 18 | { |
| 45 | TreeItem* item; | 19 | return pica_trace.writes.size(); |
| 46 | if (!parent.isValid()) { | ||
| 47 | item = root_item; | ||
| 48 | } else { | ||
| 49 | item = (TreeItem*)parent.internalPointer(); | ||
| 50 | } | ||
| 51 | return item->children.size(); | ||
| 52 | } | 20 | } |
| 53 | 21 | ||
| 54 | int GPUCommandListModel::columnCount(const QModelIndex& parent) const | 22 | int GPUCommandListModel::columnCount(const QModelIndex& parent) const |
| @@ -61,79 +29,67 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const | |||
| 61 | if (!index.isValid()) | 29 | if (!index.isValid()) |
| 62 | return QVariant(); | 30 | return QVariant(); |
| 63 | 31 | ||
| 64 | const TreeItem* item = (const TreeItem*)index.internalPointer(); | 32 | const auto& writes = pica_trace.writes; |
| 65 | 33 | const Pica::CommandProcessor::CommandHeader cmd{writes[index.row()].Id()}; | |
| 66 | if (item->type == TreeItem::COMMAND_LIST) | 34 | const u32 val{writes[index.row()].Value()}; |
| 67 | { | 35 | |
| 68 | const GraphicsDebugger::PicaCommandList& cmdlist = command_lists[item->index].second; | 36 | if (role == Qt::DisplayRole) { |
| 69 | u32 address = command_lists[item->index].first; | 37 | QString content; |
| 70 | 38 | if (index.column() == 0) { | |
| 71 | if (role == Qt::DisplayRole && index.column() == 0) | 39 | content = QString::fromLatin1(Pica::Regs::GetCommandName(cmd.cmd_id).c_str()); |
| 72 | { | 40 | content.append(" "); |
| 73 | return QVariant(QString("0x%1 bytes at 0x%2").arg(cmdlist.size(), 0, 16).arg(address, 8, 16, QLatin1Char('0'))); | 41 | } else if (index.column() == 1) { |
| 74 | } | 42 | content.append(QString("%1 ").arg(cmd.hex, 8, 16, QLatin1Char('0'))); |
| 75 | } | 43 | content.append(QString("%1 ").arg(val, 8, 16, QLatin1Char('0'))); |
| 76 | else | ||
| 77 | { | ||
| 78 | // index refers to a specific command | ||
| 79 | const GraphicsDebugger::PicaCommandList& cmdlist = command_lists[item->parent->index].second; | ||
| 80 | const GraphicsDebugger::PicaCommand& cmd = cmdlist[item->index]; | ||
| 81 | const Pica::CommandProcessor::CommandHeader& header = cmd.GetHeader(); | ||
| 82 | |||
| 83 | if (role == Qt::DisplayRole) { | ||
| 84 | QString content; | ||
| 85 | if (index.column() == 0) { | ||
| 86 | content = QString::fromLatin1(Pica::Regs::GetCommandName(header.cmd_id).c_str()); | ||
| 87 | content.append(" "); | ||
| 88 | } else if (index.column() == 1) { | ||
| 89 | for (int j = 0; j < cmd.size(); ++j) | ||
| 90 | content.append(QString("%1 ").arg(cmd[j], 8, 16, QLatin1Char('0'))); | ||
| 91 | } | ||
| 92 | |||
| 93 | return QVariant(content); | ||
| 94 | } | 44 | } |
| 45 | |||
| 46 | return QVariant(content); | ||
| 95 | } | 47 | } |
| 96 | 48 | ||
| 97 | return QVariant(); | 49 | return QVariant(); |
| 98 | } | 50 | } |
| 99 | 51 | ||
| 100 | void GPUCommandListModel::OnCommandListCalled(const GraphicsDebugger::PicaCommandList& lst, bool is_new) | 52 | void GPUCommandListModel::OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace& trace) |
| 101 | { | 53 | { |
| 102 | emit CommandListCalled(); | 54 | beginResetModel(); |
| 55 | |||
| 56 | pica_trace = trace; | ||
| 57 | |||
| 58 | endResetModel(); | ||
| 103 | } | 59 | } |
| 104 | 60 | ||
| 105 | 61 | ||
| 106 | void GPUCommandListModel::OnCommandListCalledInternal() | 62 | GPUCommandListWidget::GPUCommandListWidget(QWidget* parent) : QDockWidget(tr("Pica Command List"), parent) |
| 107 | { | 63 | { |
| 108 | beginResetModel(); | 64 | GPUCommandListModel* model = new GPUCommandListModel(this); |
| 109 | 65 | ||
| 110 | command_lists = GetDebugger()->GetCommandLists(); | 66 | QWidget* main_widget = new QWidget; |
| 111 | 67 | ||
| 112 | // delete root item and rebuild tree | 68 | QTreeView* list_widget = new QTreeView; |
| 113 | delete root_item; | 69 | list_widget->setModel(model); |
| 114 | root_item = new TreeItem(TreeItem::ROOT, 0, NULL, this); | 70 | list_widget->setFont(QFont("monospace")); |
| 71 | list_widget->setRootIsDecorated(false); | ||
| 115 | 72 | ||
| 116 | for (int command_list_idx = 0; command_list_idx < command_lists.size(); ++command_list_idx) { | 73 | QPushButton* toggle_tracing = new QPushButton(tr("Start Tracing")); |
| 117 | TreeItem* command_list_item = new TreeItem(TreeItem::COMMAND_LIST, command_list_idx, root_item, root_item); | ||
| 118 | root_item->children.push_back(command_list_item); | ||
| 119 | 74 | ||
| 120 | const GraphicsDebugger::PicaCommandList& command_list = command_lists[command_list_idx].second; | 75 | connect(toggle_tracing, SIGNAL(clicked()), this, SLOT(OnToggleTracing())); |
| 121 | for (int command_idx = 0; command_idx < command_list.size(); ++command_idx) { | 76 | connect(this, SIGNAL(TracingFinished(const Pica::DebugUtils::PicaTrace&)), |
| 122 | TreeItem* command_item = new TreeItem(TreeItem::COMMAND, command_idx, command_list_item, command_list_item); | 77 | model, SLOT(OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace&))); |
| 123 | command_list_item->children.push_back(command_item); | ||
| 124 | } | ||
| 125 | } | ||
| 126 | 78 | ||
| 127 | endResetModel(); | 79 | QVBoxLayout* main_layout = new QVBoxLayout; |
| 80 | main_layout->addWidget(list_widget); | ||
| 81 | main_layout->addWidget(toggle_tracing); | ||
| 82 | main_widget->setLayout(main_layout); | ||
| 83 | |||
| 84 | setWidget(main_widget); | ||
| 128 | } | 85 | } |
| 129 | 86 | ||
| 130 | GPUCommandListWidget::GPUCommandListWidget(QWidget* parent) : QDockWidget(tr("Pica Command List"), parent) | 87 | void GPUCommandListWidget::OnToggleTracing() |
| 131 | { | 88 | { |
| 132 | GPUCommandListModel* model = new GPUCommandListModel(this); | 89 | if (!Pica::DebugUtils::IsPicaTracing()) { |
| 133 | g_debugger.RegisterObserver(model); | 90 | Pica::DebugUtils::StartPicaTracing(); |
| 134 | 91 | } else { | |
| 135 | QTreeView* tree_widget = new QTreeView; | 92 | pica_trace = Pica::DebugUtils::FinishPicaTracing(); |
| 136 | tree_widget->setModel(model); | 93 | emit TracingFinished(*pica_trace); |
| 137 | tree_widget->setFont(QFont("monospace")); | 94 | } |
| 138 | setWidget(tree_widget); | ||
| 139 | } | 95 | } |