Path: blob/21.2-virgl/src/panfrost/ds/pan_pps_driver.cc
4560 views
/*1* Copyright © 2019-2021 Collabora, Ltd.2* Author: Antonio Caggiano <[email protected]>3* Author: Rohan Garg <[email protected]>4* Author: Robert Beckett <[email protected]>5*6* SPDX-License-Identifier: MIT7*/89#include "pan_pps_driver.h"1011#include <cstring>12#include <perfetto.h>13#include <xf86drm.h>1415#include <drm-uapi/panfrost_drm.h>16#include <perf/pan_perf.h>17#include <util/macros.h>1819#include <pps/pps.h>20#include <pps/pps_algorithm.h>2122namespace pps23{24PanfrostDriver::PanfrostDriver()25{26}2728PanfrostDriver::~PanfrostDriver()29{30}3132uint64_t PanfrostDriver::get_min_sampling_period_ns()33{34return 1000000;35}3637uint32_t find_id_within_group(uint32_t counter_id, const struct panfrost_perf_config *cfg)38{39for (uint32_t cat_id = 0; cat_id < cfg->n_categories; ++cat_id) {40const struct panfrost_perf_category *cat = &cfg->categories[cat_id];41if (counter_id < cat->n_counters) {42break;43}44counter_id -= cat->n_counters;45}4647return counter_id;48}4950std::pair<std::vector<CounterGroup>, std::vector<Counter>>51PanfrostDriver::create_available_counters(const PanfrostPerf &perf)52{53std::pair<std::vector<CounterGroup>, std::vector<Counter>> ret;54auto &[groups, counters] = ret;5556size_t cid = 0;5758for (uint32_t gid = 0; gid < perf.perf->cfg->n_categories; ++gid) {59const auto &category = perf.perf->cfg->categories[gid];60CounterGroup group = {};61group.id = gid;62group.name = category.name;6364for (; cid < category.n_counters; ++cid) {65Counter counter = {};66counter.id = cid;67counter.group = gid;6869uint32_t id_within_group = find_id_within_group(cid, perf.perf->cfg);70counter.name = category.counters[id_within_group].name;7172counter.set_getter([](const Counter &c, const Driver &d) {73auto &pan_driver = PanfrostDriver::into(d);74struct panfrost_perf *perf = pan_driver.perf->perf;75uint32_t id_within_group = find_id_within_group(c.id, perf->cfg);76const auto counter = &perf->cfg->categories[c.group].counters[id_within_group];77return int64_t(panfrost_perf_counter_read(counter, perf));78});7980group.counters.push_back(cid);8182counters.emplace_back(counter);83}8485groups.push_back(group);86}8788return ret;89}9091bool PanfrostDriver::init_perfcnt()92{93if (!dev) {94dev = std::make_unique<PanfrostDevice>(drm_device.fd);95}96if (!perf) {97perf = std::make_unique<PanfrostPerf>(*dev);98}99if (groups.empty() && counters.empty()) {100std::tie(groups, counters) = create_available_counters(*perf);101}102return true;103}104105void PanfrostDriver::enable_counter(const uint32_t counter_id)106{107enabled_counters.push_back(counters[counter_id]);108}109110void PanfrostDriver::enable_all_counters()111{112enabled_counters.resize(counters.size());113for (size_t i = 0; i < counters.size(); ++i) {114enabled_counters[i] = counters[i];115}116}117118void PanfrostDriver::enable_perfcnt(const uint64_t /* sampling_period_ns */)119{120auto res = perf->enable();121if (!check(res, "Failed to enable performance counters")) {122if (res == -ENOSYS) {123PERFETTO_FATAL("Please enable unstable ioctls with: modprobe panfrost unstable_ioctls=1");124}125PERFETTO_FATAL("Please verify graphics card");126}127}128129bool PanfrostDriver::dump_perfcnt()130{131last_dump_ts = perfetto::base::GetBootTimeNs().count();132133// Dump performance counters to buffer134if (!check(perf->dump(), "Failed to dump performance counters")) {135PERFETTO_ELOG("Skipping sample");136return false;137}138139return true;140}141142uint64_t PanfrostDriver::next()143{144auto ret = last_dump_ts;145last_dump_ts = 0;146return ret;147}148149void PanfrostDriver::disable_perfcnt()150{151perf->disable();152perf.reset();153dev.reset();154groups.clear();155counters.clear();156enabled_counters.clear();157}158159} // namespace pps160161162