Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/tool/pps/pps_config.cc
7130 views
1
/*
2
* Copyright © 2020-2021 Collabora, Ltd.
3
* Author: Antonio Caggiano <[email protected]>
4
*
5
* SPDX-License-Identifier: MIT
6
*/
7
8
#include <pps/pps_driver.h>
9
10
#include <charconv>
11
#include <cstdlib>
12
#include <cstring>
13
#include <optional>
14
#include <thread>
15
16
#include <docopt/docopt.h>
17
18
static const char *USAGE =
19
R"(pps-config
20
21
Usage:
22
pps-config info
23
pps-config dump [--gpu=<n>] [--ids=<n>] [--sec=<n>]
24
pps-config groups [--gpu=<n>]
25
pps-config counters [--gpu=<n>]
26
pps-config (-h | --help)
27
pps-config --version
28
29
Options:
30
-h --help Show this screen.
31
--version Show version.
32
--gpu=<n> GPU number to query [default: 0].
33
--ids=<n> Comma separated list of numbers.
34
--sec=<n> Seconds to wait before dumping performance counters [default: 1].
35
)";
36
37
// Tool running mode
38
enum class Mode {
39
// Show help message
40
Help,
41
42
// Show system information
43
Info,
44
45
// Show list of available counters
46
Counters,
47
48
// Groups
49
Groups,
50
51
// Dump performance counters
52
Dump,
53
};
54
55
std::vector<std::string_view> split(const std::string &list, const std::string &separator)
56
{
57
std::vector<std::string_view> ret;
58
std::string_view list_view = list;
59
while (!list_view.empty()) {
60
size_t pos = list_view.find(separator);
61
if (pos == std::string::npos) {
62
ret.push_back(list_view);
63
break;
64
}
65
ret.push_back(list_view.substr(0, pos));
66
list_view = list_view.substr(pos + separator.length(), list_view.length());
67
}
68
return ret;
69
}
70
71
std::optional<uint32_t> to_counter_id(const std::string_view &view)
72
{
73
uint32_t counter_id = 0;
74
75
auto res = std::from_chars(view.data(), view.data() + view.size(), counter_id);
76
if (res.ec == std::errc::invalid_argument) {
77
return std::nullopt;
78
}
79
80
return counter_id;
81
}
82
83
int main(int argc, const char **argv)
84
{
85
using namespace pps;
86
87
Mode mode = Mode::Help;
88
auto secs = std::chrono::seconds(1);
89
uint32_t gpu_num = 0;
90
std::vector<uint32_t> counter_ids;
91
92
auto args =
93
docopt::docopt(USAGE, {std::next(argv), std::next(argv, argc)}, true, "pps-config 0.3");
94
95
if (args["info"].asBool()) {
96
mode = Mode::Info;
97
}
98
99
if (args["dump"].asBool()) {
100
mode = Mode::Dump;
101
}
102
103
if (args["--gpu"]) {
104
gpu_num = static_cast<uint32_t>(args["--gpu"].asLong());
105
}
106
107
if (args["--ids"]) {
108
auto comma_separated_list = args["--ids"].asString();
109
std::vector<std::string_view> ids_list = split(comma_separated_list, ",");
110
111
for (auto &id : ids_list) {
112
if (auto counter_id = to_counter_id(id)) {
113
counter_ids.push_back(*counter_id);
114
} else {
115
fprintf(stderr, "Failed to parse counter ids: %s\n", comma_separated_list.c_str());
116
return EXIT_FAILURE;
117
}
118
}
119
}
120
121
if (args["--sec"]) {
122
secs = std::chrono::seconds(args["--sec"].asLong());
123
}
124
125
if (args["groups"].asBool()) {
126
mode = Mode::Groups;
127
}
128
129
if (args["counters"].asBool()) {
130
mode = Mode::Counters;
131
}
132
133
// Docopt shows the help message for us
134
if (mode == Mode::Help) {
135
return EXIT_SUCCESS;
136
}
137
138
switch (mode) {
139
default:
140
break;
141
case Mode::Info: {
142
// Header: device name, and whether it is supported or not
143
printf("#%4s %16s %16s\n", "num", "device", "support");
144
145
auto devices = DrmDevice::create_all();
146
for (auto &device : devices) {
147
auto gpu_num = device.gpu_num;
148
auto name = device.name;
149
auto driver = Driver::get_driver(std::move(device));
150
printf(" %4u %16s %16s\n", gpu_num, name.c_str(), driver ? "yes" : "no");
151
}
152
153
break;
154
}
155
case Mode::Dump: {
156
if (auto device = DrmDevice::create(gpu_num)) {
157
if (auto driver = Driver::get_driver(std::move(device.value()))) {
158
driver->init_perfcnt();
159
160
// Enable counters
161
if (counter_ids.empty()) {
162
driver->enable_all_counters();
163
} else {
164
for (auto id : counter_ids) {
165
driver->enable_counter(id);
166
}
167
}
168
169
driver->enable_perfcnt(std::chrono::nanoseconds(secs).count());
170
std::this_thread::sleep_for(std::chrono::seconds(secs));
171
172
// Try dumping until it succeeds
173
while (!driver->dump_perfcnt())
174
;
175
// Try collecting samples until it succeeds
176
while (!driver->next())
177
;
178
179
printf("#%32s %32s\n", "counter", "value");
180
for (auto &counter : driver->enabled_counters) {
181
printf(" %32s ", counter.name.c_str());
182
auto value = counter.get_value(*driver);
183
if (auto d_val = std::get_if<double>(&value)) {
184
printf("%32f\n", *d_val);
185
} else if (auto i_val = std::get_if<int64_t>(&value))
186
printf("%32li\n", *i_val);
187
else {
188
printf("%32s\n", "error");
189
}
190
}
191
}
192
}
193
break;
194
}
195
case Mode::Groups: {
196
if (auto device = DrmDevice::create(gpu_num)) {
197
if (auto driver = Driver::get_driver(std::move(device.value()))) {
198
driver->init_perfcnt();
199
printf("#%4s %32s\n", "id", "name");
200
201
for (auto &group : driver->groups) {
202
printf(" %4u %32s\n", group.id, group.name.c_str());
203
}
204
}
205
}
206
207
break;
208
}
209
case Mode::Counters: {
210
if (auto device = DrmDevice::create(gpu_num)) {
211
if (auto driver = Driver::get_driver(std::move(device.value()))) {
212
driver->init_perfcnt();
213
printf("#%4s %32s\n", "id", "name");
214
215
for (uint32_t i = 0; i < driver->counters.size(); ++i) {
216
auto &counter = driver->counters[i];
217
printf(" %4u %32s\n", counter.id, counter.name.c_str());
218
}
219
}
220
}
221
222
break;
223
}
224
} // switch
225
226
return EXIT_SUCCESS;
227
}
228
229