Mesa (main): pps: Gfx-pps config tool
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri May 7 14:04:32 UTC 2021
Module: Mesa
Branch: main
Commit: 948f780915502f8f4ddce7b2540fdf8db2d7703c
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=948f780915502f8f4ddce7b2540fdf8db2d7703c
Author: Antonio Caggiano <antonio.caggiano at collabora.com>
Date: Tue Mar 30 18:03:33 2021 +0200
pps: Gfx-pps config tool
Add helpful tool to query pps capabilites such as supported devices,
counters and counter groups, and to dump counter values to stdout.
Signed-off-by: Antonio Caggiano <antonio.caggiano at collabora.com>
Acked-by: Emma Anholt <emma at anholt.net>
Reviewed-by: Rob Clark <robdclark at chromium.org>
Reviewed-by: John Bates <jbates at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9652>
---
src/tool/pps/meson.build | 17 ++++
src/tool/pps/pps_config.cc | 227 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 244 insertions(+)
diff --git a/src/tool/pps/meson.build b/src/tool/pps/meson.build
index c379a74c847..9ca5e57e003 100644
--- a/src/tool/pps/meson.build
+++ b/src/tool/pps/meson.build
@@ -42,3 +42,20 @@ executable(
cpp_args: '-std=c++17',
install: true
)
+
+config_sources = [
+ 'pps_config.cc'
+]
+
+dep_docopt = dependency('docopt', required: false)
+
+if dep_docopt.found()
+ executable(
+ 'pps-config',
+ sources: config_sources,
+ include_directories: [include_pps, inc_src],
+ dependencies: [dep_pps, dep_docopt],
+ cpp_args: '-std=c++17',
+ install: true
+ )
+endif
diff --git a/src/tool/pps/pps_config.cc b/src/tool/pps/pps_config.cc
new file mode 100644
index 00000000000..7d8fb2caeb0
--- /dev/null
+++ b/src/tool/pps/pps_config.cc
@@ -0,0 +1,227 @@
+/*
+ * Copyright © 2020-2021 Collabora, Ltd.
+ * Author: Antonio Caggiano <antonio.caggiano at collabora.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <pps/pps_driver.h>
+
+#include <charconv>
+#include <cstdlib>
+#include <cstring>
+#include <optional>
+#include <thread>
+
+#include <docopt/docopt.h>
+
+static const char *USAGE =
+ R"(pps-config
+
+ Usage:
+ pps-config info
+ pps-config dump [--gpu=<n>] [--ids=<n>] [--sec=<n>]
+ pps-config groups [--gpu=<n>]
+ pps-config counters [--gpu=<n>]
+ pps-config (-h | --help)
+ pps-config --version
+
+ Options:
+ -h --help Show this screen.
+ --version Show version.
+ --gpu=<n> GPU number to query [default: 0].
+ --ids=<n> Comma separated list of numbers.
+ --sec=<n> Seconds to wait before dumping performance counters [default: 1].
+)";
+
+// Tool running mode
+enum class Mode {
+ // Show help message
+ Help,
+
+ // Show system information
+ Info,
+
+ // Show list of available counters
+ Counters,
+
+ // Groups
+ Groups,
+
+ // Dump performance counters
+ Dump,
+};
+
+std::vector<std::string_view> split(const std::string &list, const std::string &separator)
+{
+ std::vector<std::string_view> ret;
+ std::string_view list_view = list;
+ while (!list_view.empty()) {
+ size_t pos = list_view.find(separator);
+ if (pos == std::string::npos) {
+ ret.push_back(list_view);
+ break;
+ }
+ ret.push_back(list_view.substr(0, pos));
+ list_view = list_view.substr(pos + separator.length(), list_view.length());
+ }
+ return ret;
+}
+
+std::optional<uint32_t> to_counter_id(const std::string_view &view)
+{
+ uint32_t counter_id = 0;
+
+ auto res = std::from_chars(view.data(), view.data() + view.size(), counter_id);
+ if (res.ec == std::errc::invalid_argument) {
+ return std::nullopt;
+ }
+
+ return counter_id;
+}
+
+int main(int argc, const char **argv)
+{
+ using namespace pps;
+
+ Mode mode = Mode::Help;
+ auto secs = std::chrono::seconds(1);
+ uint32_t gpu_num = 0;
+ std::vector<uint32_t> counter_ids;
+
+ auto args =
+ docopt::docopt(USAGE, {std::next(argv), std::next(argv, argc)}, true, "pps-config 0.3");
+
+ if (args["info"].asBool()) {
+ mode = Mode::Info;
+ }
+
+ if (args["dump"].asBool()) {
+ mode = Mode::Dump;
+ }
+
+ if (args["--gpu"]) {
+ gpu_num = static_cast<uint32_t>(args["--gpu"].asLong());
+ }
+
+ if (args["--ids"]) {
+ auto comma_separated_list = args["--ids"].asString();
+ std::vector<std::string_view> ids_list = split(comma_separated_list, ",");
+
+ for (auto &id : ids_list) {
+ if (auto counter_id = to_counter_id(id)) {
+ counter_ids.push_back(*counter_id);
+ } else {
+ fprintf(stderr, "Failed to parse counter ids: %s\n", comma_separated_list.c_str());
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ if (args["--sec"]) {
+ secs = std::chrono::seconds(args["--sec"].asLong());
+ }
+
+ if (args["groups"].asBool()) {
+ mode = Mode::Groups;
+ }
+
+ if (args["counters"].asBool()) {
+ mode = Mode::Counters;
+ }
+
+ // Docopt shows the help message for us
+ if (mode == Mode::Help) {
+ return EXIT_SUCCESS;
+ }
+
+ switch (mode) {
+ default:
+ break;
+ case Mode::Info: {
+ // Header: device name, and whether it is supported or not
+ printf("#%4s %16s %16s\n", "num", "device", "support");
+
+ auto devices = DrmDevice::create_all();
+ for (auto &device : devices) {
+ auto gpu_num = device.gpu_num;
+ auto name = device.name;
+ auto driver = Driver::get_driver(std::move(device));
+ printf(" %4u %16s %16s\n", gpu_num, name.c_str(), driver ? "yes" : "no");
+ }
+
+ break;
+ }
+ case Mode::Dump: {
+ if (auto device = DrmDevice::create(gpu_num)) {
+ if (auto driver = Driver::get_driver(std::move(device.value()))) {
+ driver->init_perfcnt();
+
+ // Enable counters
+ if (counter_ids.empty()) {
+ driver->enable_all_counters();
+ } else {
+ for (auto id : counter_ids) {
+ driver->enable_counter(id);
+ }
+ }
+
+ driver->enable_perfcnt(std::chrono::nanoseconds(secs).count());
+ std::this_thread::sleep_for(std::chrono::seconds(secs));
+
+ // Try dumping until it succeeds
+ while (!driver->dump_perfcnt())
+ ;
+ // Try collecting samples until it succeeds
+ while (!driver->next())
+ ;
+
+ printf("#%32s %32s\n", "counter", "value");
+ for (auto &counter : driver->enabled_counters) {
+ printf(" %32s ", counter.name.c_str());
+ auto value = counter.get_value(*driver);
+ if (auto d_val = std::get_if<double>(&value)) {
+ printf("%32f\n", *d_val);
+ } else if (auto i_val = std::get_if<int64_t>(&value))
+ printf("%32li\n", *i_val);
+ else {
+ printf("%32s\n", "error");
+ }
+ }
+ }
+ }
+ break;
+ }
+ case Mode::Groups: {
+ if (auto device = DrmDevice::create(gpu_num)) {
+ if (auto driver = Driver::get_driver(std::move(device.value()))) {
+ driver->init_perfcnt();
+ printf("#%4s %32s\n", "id", "name");
+
+ for (auto &group : driver->groups) {
+ printf(" %4u %32s\n", group.id, group.name.c_str());
+ }
+ }
+ }
+
+ break;
+ }
+ case Mode::Counters: {
+ if (auto device = DrmDevice::create(gpu_num)) {
+ if (auto driver = Driver::get_driver(std::move(device.value()))) {
+ driver->init_perfcnt();
+ printf("#%4s %32s\n", "id", "name");
+
+ for (uint32_t i = 0; i < driver->counters.size(); ++i) {
+ auto &counter = driver->counters[i];
+ printf(" %4u %32s\n", counter.id, counter.name.c_str());
+ }
+ }
+ }
+
+ break;
+ }
+ } // switch
+
+ return EXIT_SUCCESS;
+}
More information about the mesa-commit
mailing list