summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2014-05-18 19:59:36 +0200
committerGravatar bunnei2014-06-12 06:10:52 -0400
commitb0051b2203d8319e57603ee6cbfaa5cd798de060 (patch)
tree8d331f1958fbf0dda7215e597faff818a7bda247 /src
parentcitra-qt: Add command list view. (diff)
downloadyuzu-b0051b2203d8319e57603ee6cbfaa5cd798de060.tar.gz
yuzu-b0051b2203d8319e57603ee6cbfaa5cd798de060.tar.xz
yuzu-b0051b2203d8319e57603ee6cbfaa5cd798de060.zip
Refine command list debugging functionality and its qt interface.
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/debugger/graphics_cmdlists.cpp98
-rw-r--r--src/citra_qt/debugger/graphics_cmdlists.hxx28
-rw-r--r--src/video_core/gpu_debugger.h23
-rw-r--r--src/video_core/pica.h2
4 files changed, 124 insertions, 27 deletions
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp
index 576882e8a..d07645e78 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.cpp
+++ b/src/citra_qt/debugger/graphics_cmdlists.cpp
@@ -3,18 +3,57 @@
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 "graphics_cmdlists.hxx"
6#include <QListView> 6#include <QTreeView>
7 7
8extern GraphicsDebugger g_debugger; 8extern GraphicsDebugger g_debugger;
9 9
10GPUCommandListModel::GPUCommandListModel(QObject* parent) : QAbstractListModel(parent), row_count(0) 10GPUCommandListModel::GPUCommandListModel(QObject* parent) : QAbstractItemModel(parent)
11{ 11{
12 root_item = new TreeItem(TreeItem::ROOT, 0, NULL, this);
13
12 connect(this, SIGNAL(CommandListCalled()), this, SLOT(OnCommandListCalledInternal()), Qt::UniqueConnection); 14 connect(this, SIGNAL(CommandListCalled()), this, SLOT(OnCommandListCalledInternal()), Qt::UniqueConnection);
13} 15}
14 16
17QModelIndex 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
30QModelIndex GPUCommandListModel::parent(const QModelIndex& child) const
31{
32 if (!child.isValid())
33 return QModelIndex();
34
35 TreeItem* item = (TreeItem*)child.internalPointer();
36
37 if (item->parent == NULL)
38 return QModelIndex();
39
40 return createIndex(item->parent->index, 0, item->parent);
41}
42
15int GPUCommandListModel::rowCount(const QModelIndex& parent) const 43int GPUCommandListModel::rowCount(const QModelIndex& parent) const
16{ 44{
17 return row_count; 45 TreeItem* item;
46 if (!parent.isValid()) {
47 item = root_item;
48 } else {
49 item = (TreeItem*)parent.internalPointer();
50 }
51 return item->children.size();
52}
53
54int GPUCommandListModel::columnCount(const QModelIndex& parent) const
55{
56 return 1;
18} 57}
19 58
20QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const 59QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const
@@ -22,19 +61,33 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const
22 if (!index.isValid()) 61 if (!index.isValid())
23 return QVariant(); 62 return QVariant();
24 63
25 int idx = index.row(); 64 const TreeItem* item = (const TreeItem*)index.internalPointer();
26 if (role == Qt::DisplayRole) 65
66 if (item->type == TreeItem::COMMAND_LIST)
27 { 67 {
28 QString content; 68 const GraphicsDebugger::PicaCommandList& cmdlist = command_lists[item->index].second;
29 const GraphicsDebugger::PicaCommandList& cmdlist = command_list[idx].second; 69 u32 address = command_lists[item->index].first;
30 for (int i = 0; i < cmdlist.size(); ++i) 70
71 if (role == Qt::DisplayRole)
31 { 72 {
32 const GraphicsDebugger::PicaCommand& cmd = cmdlist[i]; 73 return QVariant(QString("0x%1 bytes at 0x%2").arg(cmdlist.size(), 0, 16).arg(address, 8, 16, QLatin1Char('0')));
74 }
75 }
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
82 if (role == Qt::DisplayRole) {
83 QString content;
33 for (int j = 0; j < cmd.size(); ++j) 84 for (int j = 0; j < cmd.size(); ++j)
34 content.append(QString("%1 ").arg(cmd[j], 8, 16, QLatin1Char('0'))); 85 content.append(QString("%1 ").arg(cmd[j], 8, 16, QLatin1Char('0')));
86
87 return QVariant(content);
35 } 88 }
36 return QVariant(content);
37 } 89 }
90
38 return QVariant(); 91 return QVariant();
39} 92}
40 93
@@ -48,8 +101,22 @@ void GPUCommandListModel::OnCommandListCalledInternal()
48{ 101{
49 beginResetModel(); 102 beginResetModel();
50 103
51 command_list = GetDebugger()->GetCommandLists(); 104 command_lists = GetDebugger()->GetCommandLists();
52 row_count = command_list.size(); 105
106 // delete root item and rebuild tree
107 delete root_item;
108 root_item = new TreeItem(TreeItem::ROOT, 0, NULL, this);
109
110 for (int command_list_idx = 0; command_list_idx < command_lists.size(); ++command_list_idx) {
111 TreeItem* command_list_item = new TreeItem(TreeItem::COMMAND_LIST, command_list_idx, root_item, root_item);
112 root_item->children.push_back(command_list_item);
113
114 const GraphicsDebugger::PicaCommandList& command_list = command_lists[command_list_idx].second;
115 for (int command_idx = 0; command_idx < command_list.size(); ++command_idx) {
116 TreeItem* command_item = new TreeItem(TreeItem::COMMAND, command_idx, command_list_item, command_list_item);
117 command_list_item->children.push_back(command_item);
118 }
119 }
53 120
54 endResetModel(); 121 endResetModel();
55} 122}
@@ -59,7 +126,8 @@ GPUCommandListWidget::GPUCommandListWidget(QWidget* parent) : QDockWidget(tr("Pi
59 GPUCommandListModel* model = new GPUCommandListModel(this); 126 GPUCommandListModel* model = new GPUCommandListModel(this);
60 g_debugger.RegisterObserver(model); 127 g_debugger.RegisterObserver(model);
61 128
62 QListView* list_widget = new QListView; 129 QTreeView* tree_widget = new QTreeView;
63 list_widget->setModel(model); 130 tree_widget->setModel(model);
64 setWidget(list_widget); 131 tree_widget->setFont(QFont("monospace"));
132 setWidget(tree_widget);
65} 133}
diff --git a/src/citra_qt/debugger/graphics_cmdlists.hxx b/src/citra_qt/debugger/graphics_cmdlists.hxx
index bac23c643..b4e6e3c8a 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.hxx
+++ b/src/citra_qt/debugger/graphics_cmdlists.hxx
@@ -4,18 +4,22 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <QAbstractListModel> 7#include <QAbstractItemModel>
8#include <QDockWidget> 8#include <QDockWidget>
9 9
10#include "video_core/gpu_debugger.h" 10#include "video_core/gpu_debugger.h"
11 11
12class GPUCommandListModel : public QAbstractListModel, public GraphicsDebugger::DebuggerObserver 12// TODO: Rename class, since it's not actually a list model anymore...
13class GPUCommandListModel : public QAbstractItemModel, public GraphicsDebugger::DebuggerObserver
13{ 14{
14 Q_OBJECT 15 Q_OBJECT
15 16
16public: 17public:
17 GPUCommandListModel(QObject* parent); 18 GPUCommandListModel(QObject* parent);
18 19
20 QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
21 QModelIndex parent(const QModelIndex& child) const;
22 int columnCount(const QModelIndex& parent = QModelIndex()) const;
19 int rowCount(const QModelIndex& parent = QModelIndex()) const override; 23 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
20 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; 24 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
21 25
@@ -29,8 +33,24 @@ signals:
29 void CommandListCalled(); 33 void CommandListCalled();
30 34
31private: 35private:
32 int row_count; 36 struct TreeItem : public QObject
33 std::vector<std::pair<u32,GraphicsDebugger::PicaCommandList>> command_list; 37 {
38 enum Type {
39 ROOT,
40 COMMAND_LIST,
41 COMMAND
42 };
43
44 TreeItem(Type type, int index, TreeItem* item_parent, QObject* parent) : QObject(parent), type(type), index(index), parent(item_parent) {}
45
46 Type type;
47 int index;
48 std::vector<TreeItem*> children;
49 TreeItem* parent;
50 };
51
52 std::vector<std::pair<u32,GraphicsDebugger::PicaCommandList>> command_lists;
53 TreeItem* root_item;
34}; 54};
35 55
36class GPUCommandListWidget : public QDockWidget 56class GPUCommandListWidget : public QDockWidget
diff --git a/src/video_core/gpu_debugger.h b/src/video_core/gpu_debugger.h
index 7ad595493..5ece0a8b7 100644
--- a/src/video_core/gpu_debugger.h
+++ b/src/video_core/gpu_debugger.h
@@ -22,7 +22,8 @@ public:
22 { 22 {
23 Pica::CommandHeader& GetHeader() 23 Pica::CommandHeader& GetHeader()
24 { 24 {
25 return *(Pica::CommandHeader*)&(front()); 25 u32& val = at(1);
26 return *(Pica::CommandHeader*)&val;
26 } 27 }
27 }; 28 };
28 29
@@ -90,14 +91,20 @@ public:
90 91
91 void CommandListCalled(u32 address, u32* command_list, u32 size_in_words) 92 void CommandListCalled(u32 address, u32* command_list, u32 size_in_words)
92 { 93 {
93 // TODO: Decoding fun
94
95 // For now, just treating the whole command list as a single command
96 PicaCommandList cmdlist; 94 PicaCommandList cmdlist;
97 cmdlist.push_back(PicaCommand()); 95 for (u32* parse_pointer = command_list; parse_pointer < command_list + size_in_words;)
98 auto& cmd = cmdlist[0]; 96 {
99 cmd.reserve(size_in_words); 97 const Pica::CommandHeader header = static_cast<Pica::CommandHeader>(parse_pointer[1]);
100 std::copy(command_list, command_list+size_in_words, std::back_inserter(cmd)); 98
99 cmdlist.push_back(PicaCommand());
100 auto& cmd = cmdlist.back();
101
102 size_t size = 2 + header.extra_data_length;
103 cmd.reserve(size);
104 std::copy(parse_pointer, parse_pointer + size, std::back_inserter(cmd));
105
106 parse_pointer += size;
107 }
101 108
102 auto obj = std::pair<u32,PicaCommandList>(address, cmdlist); 109 auto obj = std::pair<u32,PicaCommandList>(address, cmdlist);
103 auto it = std::find(command_lists.begin(), command_lists.end(), obj); 110 auto it = std::find(command_lists.begin(), command_lists.end(), obj);
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index dab861408..8ebe0dc3c 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -24,6 +24,8 @@ enum class CommandId : u32
24}; 24};
25 25
26union CommandHeader { 26union CommandHeader {
27 CommandHeader(u32 h) : hex(h) {}
28
27 u32 hex; 29 u32 hex;
28 30
29 BitField< 0, 16, CommandId> cmd_id; 31 BitField< 0, 16, CommandId> cmd_id;