Path: blob/21.2-virgl/src/tool/pps/pps_config.cc
7130 views
/*1* Copyright © 2020-2021 Collabora, Ltd.2* Author: Antonio Caggiano <[email protected]>3*4* SPDX-License-Identifier: MIT5*/67#include <pps/pps_driver.h>89#include <charconv>10#include <cstdlib>11#include <cstring>12#include <optional>13#include <thread>1415#include <docopt/docopt.h>1617static const char *USAGE =18R"(pps-config1920Usage:21pps-config info22pps-config dump [--gpu=<n>] [--ids=<n>] [--sec=<n>]23pps-config groups [--gpu=<n>]24pps-config counters [--gpu=<n>]25pps-config (-h | --help)26pps-config --version2728Options:29-h --help Show this screen.30--version Show version.31--gpu=<n> GPU number to query [default: 0].32--ids=<n> Comma separated list of numbers.33--sec=<n> Seconds to wait before dumping performance counters [default: 1].34)";3536// Tool running mode37enum class Mode {38// Show help message39Help,4041// Show system information42Info,4344// Show list of available counters45Counters,4647// Groups48Groups,4950// Dump performance counters51Dump,52};5354std::vector<std::string_view> split(const std::string &list, const std::string &separator)55{56std::vector<std::string_view> ret;57std::string_view list_view = list;58while (!list_view.empty()) {59size_t pos = list_view.find(separator);60if (pos == std::string::npos) {61ret.push_back(list_view);62break;63}64ret.push_back(list_view.substr(0, pos));65list_view = list_view.substr(pos + separator.length(), list_view.length());66}67return ret;68}6970std::optional<uint32_t> to_counter_id(const std::string_view &view)71{72uint32_t counter_id = 0;7374auto res = std::from_chars(view.data(), view.data() + view.size(), counter_id);75if (res.ec == std::errc::invalid_argument) {76return std::nullopt;77}7879return counter_id;80}8182int main(int argc, const char **argv)83{84using namespace pps;8586Mode mode = Mode::Help;87auto secs = std::chrono::seconds(1);88uint32_t gpu_num = 0;89std::vector<uint32_t> counter_ids;9091auto args =92docopt::docopt(USAGE, {std::next(argv), std::next(argv, argc)}, true, "pps-config 0.3");9394if (args["info"].asBool()) {95mode = Mode::Info;96}9798if (args["dump"].asBool()) {99mode = Mode::Dump;100}101102if (args["--gpu"]) {103gpu_num = static_cast<uint32_t>(args["--gpu"].asLong());104}105106if (args["--ids"]) {107auto comma_separated_list = args["--ids"].asString();108std::vector<std::string_view> ids_list = split(comma_separated_list, ",");109110for (auto &id : ids_list) {111if (auto counter_id = to_counter_id(id)) {112counter_ids.push_back(*counter_id);113} else {114fprintf(stderr, "Failed to parse counter ids: %s\n", comma_separated_list.c_str());115return EXIT_FAILURE;116}117}118}119120if (args["--sec"]) {121secs = std::chrono::seconds(args["--sec"].asLong());122}123124if (args["groups"].asBool()) {125mode = Mode::Groups;126}127128if (args["counters"].asBool()) {129mode = Mode::Counters;130}131132// Docopt shows the help message for us133if (mode == Mode::Help) {134return EXIT_SUCCESS;135}136137switch (mode) {138default:139break;140case Mode::Info: {141// Header: device name, and whether it is supported or not142printf("#%4s %16s %16s\n", "num", "device", "support");143144auto devices = DrmDevice::create_all();145for (auto &device : devices) {146auto gpu_num = device.gpu_num;147auto name = device.name;148auto driver = Driver::get_driver(std::move(device));149printf(" %4u %16s %16s\n", gpu_num, name.c_str(), driver ? "yes" : "no");150}151152break;153}154case Mode::Dump: {155if (auto device = DrmDevice::create(gpu_num)) {156if (auto driver = Driver::get_driver(std::move(device.value()))) {157driver->init_perfcnt();158159// Enable counters160if (counter_ids.empty()) {161driver->enable_all_counters();162} else {163for (auto id : counter_ids) {164driver->enable_counter(id);165}166}167168driver->enable_perfcnt(std::chrono::nanoseconds(secs).count());169std::this_thread::sleep_for(std::chrono::seconds(secs));170171// Try dumping until it succeeds172while (!driver->dump_perfcnt())173;174// Try collecting samples until it succeeds175while (!driver->next())176;177178printf("#%32s %32s\n", "counter", "value");179for (auto &counter : driver->enabled_counters) {180printf(" %32s ", counter.name.c_str());181auto value = counter.get_value(*driver);182if (auto d_val = std::get_if<double>(&value)) {183printf("%32f\n", *d_val);184} else if (auto i_val = std::get_if<int64_t>(&value))185printf("%32li\n", *i_val);186else {187printf("%32s\n", "error");188}189}190}191}192break;193}194case Mode::Groups: {195if (auto device = DrmDevice::create(gpu_num)) {196if (auto driver = Driver::get_driver(std::move(device.value()))) {197driver->init_perfcnt();198printf("#%4s %32s\n", "id", "name");199200for (auto &group : driver->groups) {201printf(" %4u %32s\n", group.id, group.name.c_str());202}203}204}205206break;207}208case Mode::Counters: {209if (auto device = DrmDevice::create(gpu_num)) {210if (auto driver = Driver::get_driver(std::move(device.value()))) {211driver->init_perfcnt();212printf("#%4s %32s\n", "id", "name");213214for (uint32_t i = 0; i < driver->counters.size(); ++i) {215auto &counter = driver->counters[i];216printf(" %4u %32s\n", counter.id, counter.name.c_str());217}218}219}220221break;222}223} // switch224225return EXIT_SUCCESS;226}227228229