Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/GPU/Debugger/Debugger.cpp
3186 views
1
// Copyright (c) 2018- PPSSPP Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
#include <vector>
19
#include "Common/Log.h"
20
#include "Common/StringUtils.h"
21
#include "GPU/GPU.h"
22
#include "GPU/Debugger/Breakpoints.h"
23
#include "GPU/Debugger/Debugger.h"
24
#include "GPU/Debugger/Stepping.h"
25
26
namespace GPUDebug {
27
28
const char *BreakNextToString(BreakNext next) {
29
switch (next) {
30
case BreakNext::NONE: return "NONE,";
31
case BreakNext::OP: return "OP";
32
case BreakNext::DRAW: return "DRAW";
33
case BreakNext::TEX: return "TEX";
34
case BreakNext::NONTEX: return "NONTEX";
35
case BreakNext::FRAME: return "FRAME";
36
case BreakNext::VSYNC: return "VSYNC";
37
case BreakNext::PRIM: return "PRIM";
38
case BreakNext::CURVE: return "CURVE";
39
case BreakNext::BLOCK_TRANSFER: return "BLOCK_TRANSFER";
40
case BreakNext::COUNT: return "COUNT";
41
case BreakNext::DEBUG_RUN: return "DEBUG_RUN";
42
default: return "N/A";
43
}
44
}
45
46
static bool ParseRange(const std::string &s, std::pair<int, int> &range) {
47
int c = sscanf(s.c_str(), "%d-%d", &range.first, &range.second);
48
if (c == 0)
49
return false;
50
if (c == 1)
51
range.second = range.first;
52
return true;
53
}
54
55
bool ParsePrimRanges(std::string_view rule, std::vector<std::pair<int, int>> *output) {
56
constexpr int MAX_PRIMS = 0x7FFFFFFF;
57
58
std::vector<std::string> parts;
59
SplitString(rule, ',', parts);
60
61
// Parse expressions like: 0 or 0-1,4-5 or !2 or !2-3 or !2,!3
62
std::vector<std::pair<int, int>> updated;
63
for (auto &part : parts) {
64
std::pair<int, int> range;
65
if (part.size() > 1 && part[0] == '!') {
66
if (!ParseRange(part.substr(1), range))
67
return false;
68
69
// If there's nothing yet, add everything else.
70
if (updated.empty()) {
71
if (range.first > 0)
72
updated.emplace_back(0, range.first - 1);
73
if (range.second < MAX_PRIMS)
74
updated.emplace_back(range.second + 1, MAX_PRIMS);
75
continue;
76
}
77
78
// Otherwise, remove this range from any existing.
79
for (size_t i = 0; i < updated.size(); ++i) {
80
auto &sub = updated[i];
81
if (sub.second < range.first || sub.first > range.second)
82
continue;
83
if (sub.first >= range.first && sub.second <= range.second) {
84
// Entire subrange is inside the deleted entries, nuke.
85
sub.first = -1;
86
sub.second = -1;
87
continue;
88
}
89
if (sub.first < range.first && sub.second > range.second) {
90
// We're slicing a hole in this subrange.
91
int next = sub.second;
92
sub.second = range.first - 1;
93
updated.emplace_back(range.second + 1, next);
94
continue;
95
}
96
97
// If we got here, we're simply clipping the subrange.
98
if (sub.first < range.first && sub.second >= range.first && sub.second <= range.second)
99
sub.second = range.first - 1;
100
if (sub.first >= range.first && sub.first <= range.second && sub.second < range.second)
101
sub.first = range.second + 1;
102
}
103
} else {
104
if (!ParseRange(part, range))
105
return false;
106
107
updated.push_back(range);
108
}
109
}
110
*output = updated;
111
return true;
112
}
113
114
}
115
116