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