mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
pan/pps: Delegate more tasks to PanfrostPerf
This makes it so that everything that uses the pan_perf C lib is hidden inside PanfrostPerf instead of being used directly from the pps driver. Co-Authored-by: Lukas Zapolskas <lukas.zapolskas@arm.com>
This commit is contained in:
parent
8141fd7342
commit
51992c8556
3 changed files with 137 additions and 66 deletions
|
|
@ -33,46 +33,13 @@ PanfrostDriver::~PanfrostDriver()
|
|||
uint64_t
|
||||
PanfrostDriver::get_min_sampling_period_ns()
|
||||
{
|
||||
return 1000000;
|
||||
return perf->get_min_sampling_period_ns();
|
||||
}
|
||||
|
||||
std::pair<std::vector<CounterGroup>, std::vector<Counter>>
|
||||
PanfrostDriver::create_available_counters(const PanfrostPerf &perf)
|
||||
{
|
||||
std::pair<std::vector<CounterGroup>, std::vector<Counter>> ret;
|
||||
auto &[groups, counters] = ret;
|
||||
|
||||
size_t cid = 0;
|
||||
|
||||
for (uint32_t gid = 0; gid < perf.perf->cfg->n_categories; ++gid) {
|
||||
const auto &category = perf.perf->cfg->categories[gid];
|
||||
CounterGroup group = {};
|
||||
group.id = gid;
|
||||
group.name = category.name;
|
||||
|
||||
for (size_t id = 0; id < category.n_counters; ++id) {
|
||||
Counter counter = {};
|
||||
counter.id = cid;
|
||||
counter.group = gid;
|
||||
|
||||
counter.name = category.counters[id].name;
|
||||
|
||||
counter.set_getter([=](const Counter &c, const Driver &d) {
|
||||
auto &pan_driver = PanfrostDriver::into(d);
|
||||
struct pan_perf *perf = pan_driver.perf->perf;
|
||||
const auto counter = &perf->cfg->categories[gid].counters[id];
|
||||
return int64_t(pan_perf_counter_read(counter, perf));
|
||||
});
|
||||
|
||||
group.counters.push_back(cid++);
|
||||
|
||||
counters.emplace_back(counter);
|
||||
}
|
||||
|
||||
groups.push_back(group);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return perf.create_available_counters();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -81,9 +48,12 @@ PanfrostDriver::init_perfcnt()
|
|||
if (!dev) {
|
||||
dev = std::make_unique<PanfrostDevice>(drm_device.fd);
|
||||
}
|
||||
|
||||
if (!perf) {
|
||||
perf = std::make_unique<PanfrostPerf>(*dev);
|
||||
}
|
||||
|
||||
perf->init_perfcnt(drm_device.fd);
|
||||
if (groups.empty() && counters.empty()) {
|
||||
std::tie(groups, counters) = create_available_counters(*perf);
|
||||
}
|
||||
|
|
@ -106,9 +76,9 @@ PanfrostDriver::enable_all_counters()
|
|||
}
|
||||
|
||||
void
|
||||
PanfrostDriver::enable_perfcnt(const uint64_t /* sampling_period_ns */)
|
||||
PanfrostDriver::enable_perfcnt(const uint64_t sampling_period_ns)
|
||||
{
|
||||
auto res = perf->enable();
|
||||
auto res = perf->enable_perfcnt(sampling_period_ns);
|
||||
if (!check(res, "Failed to enable performance counters")) {
|
||||
if (res == -ENOSYS) {
|
||||
PERFETTO_FATAL(
|
||||
|
|
@ -121,10 +91,8 @@ PanfrostDriver::enable_perfcnt(const uint64_t /* sampling_period_ns */)
|
|||
bool
|
||||
PanfrostDriver::dump_perfcnt()
|
||||
{
|
||||
last_dump_ts = perfetto::base::GetBootTimeNs().count();
|
||||
|
||||
// Dump performance counters to buffer
|
||||
if (!check(perf->dump(), "Failed to dump performance counters")) {
|
||||
if (!check(perf->dump_perfcnt(), "Failed to dump performance counters")) {
|
||||
PERFETTO_ELOG("Skipping sample");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -135,15 +103,13 @@ PanfrostDriver::dump_perfcnt()
|
|||
uint64_t
|
||||
PanfrostDriver::next()
|
||||
{
|
||||
auto ret = last_dump_ts;
|
||||
last_dump_ts = 0;
|
||||
return ret;
|
||||
return perf->next();
|
||||
}
|
||||
|
||||
void
|
||||
PanfrostDriver::disable_perfcnt()
|
||||
{
|
||||
perf->disable();
|
||||
perf->disable_perfcnt();
|
||||
perf.reset();
|
||||
dev.reset();
|
||||
groups.clear();
|
||||
|
|
@ -154,20 +120,19 @@ PanfrostDriver::disable_perfcnt()
|
|||
uint32_t
|
||||
PanfrostDriver::gpu_clock_id() const
|
||||
{
|
||||
return perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
|
||||
return perf->gpu_clock_id();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
PanfrostDriver::gpu_timestamp() const
|
||||
{
|
||||
return perfetto::base::GetBootTimeNs().count();
|
||||
return perf->gpu_timestamp();
|
||||
}
|
||||
|
||||
bool
|
||||
PanfrostDriver::cpu_gpu_timestamp(uint64_t &, uint64_t &) const
|
||||
PanfrostDriver::cpu_gpu_timestamp(uint64_t &cpu_timestamp, uint64_t &gpu_timestamp) const
|
||||
{
|
||||
/* Not supported */
|
||||
return false;
|
||||
return perf->cpu_gpu_timestamp(cpu_timestamp, gpu_timestamp);
|
||||
}
|
||||
|
||||
} // namespace pps
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include "pan_pps_perf.h"
|
||||
#include "pan_pps_driver.h"
|
||||
|
||||
#include <lib/kmod/pan_kmod.h>
|
||||
#include <perf/pan_perf.h>
|
||||
|
|
@ -12,14 +13,12 @@
|
|||
#include <util/ralloc.h>
|
||||
|
||||
namespace pps {
|
||||
|
||||
PanfrostPerf::PanfrostPerf(const PanfrostDevice &dev)
|
||||
: perf{reinterpret_cast<struct pan_perf *>(
|
||||
rzalloc(nullptr, struct pan_perf))}
|
||||
{
|
||||
perf = reinterpret_cast<struct pan_perf *>(
|
||||
rzalloc(nullptr, struct pan_perf));
|
||||
assert(perf);
|
||||
assert(dev.fd >= 0);
|
||||
pan_perf_init(perf, dev.fd);
|
||||
}
|
||||
|
||||
PanfrostPerf::~PanfrostPerf()
|
||||
|
|
@ -31,7 +30,7 @@ PanfrostPerf::~PanfrostPerf()
|
|||
}
|
||||
}
|
||||
|
||||
PanfrostPerf::PanfrostPerf(PanfrostPerf &&o): perf{o.perf}
|
||||
PanfrostPerf::PanfrostPerf(PanfrostPerf &&o): perf(o.perf)
|
||||
{
|
||||
o.perf = nullptr;
|
||||
}
|
||||
|
|
@ -43,25 +42,116 @@ PanfrostPerf::operator=(PanfrostPerf &&o)
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
PanfrostPerf::init_perfcnt(int fd)
|
||||
{
|
||||
pan_perf_init(perf, fd);
|
||||
|
||||
return perf != NULL;
|
||||
}
|
||||
|
||||
int
|
||||
PanfrostPerf::enable() const
|
||||
PanfrostPerf::enable_perfcnt(uint64_t /* sampling_period_ns */)
|
||||
{
|
||||
assert(perf);
|
||||
return pan_perf_enable(perf);
|
||||
}
|
||||
|
||||
void
|
||||
PanfrostPerf::disable() const
|
||||
PanfrostPerf::disable_perfcnt()
|
||||
{
|
||||
assert(perf);
|
||||
pan_perf_disable(perf);
|
||||
}
|
||||
|
||||
int
|
||||
PanfrostPerf::dump() const
|
||||
bool
|
||||
PanfrostPerf::dump_perfcnt()
|
||||
{
|
||||
assert(perf);
|
||||
return pan_perf_dump(perf);
|
||||
last_dump_ts = perfetto::base::GetBootTimeNs().count();
|
||||
|
||||
int ret = pan_perf_dump(perf);
|
||||
|
||||
return !!(ret >= 0);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
PanfrostPerf::get_min_sampling_period_ns()
|
||||
{
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
void *
|
||||
PanfrostPerf::get_subinstance() {
|
||||
return perf;
|
||||
}
|
||||
|
||||
std::pair<std::vector<CounterGroup>, std::vector<Counter>>
|
||||
PanfrostPerf::create_available_counters() const
|
||||
{
|
||||
std::pair<std::vector<CounterGroup>, std::vector<Counter>> ret;
|
||||
auto &[groups, counters] = ret;
|
||||
|
||||
size_t cid = 0;
|
||||
|
||||
for (uint32_t gid = 0; gid < perf->cfg->n_categories; ++gid) {
|
||||
const auto &category = perf->cfg->categories[gid];
|
||||
CounterGroup group = {};
|
||||
group.id = gid;
|
||||
group.name = category.name;
|
||||
|
||||
for (size_t id = 0; cid < category.n_counters; ++cid) {
|
||||
Counter counter = {};
|
||||
counter.id = cid;
|
||||
counter.group = gid;
|
||||
|
||||
counter.name = category.counters[id].name;
|
||||
|
||||
counter.set_getter([=](const Counter &c, const Driver &d) {
|
||||
auto &pan_driver = PanfrostDriver::into(d);
|
||||
struct pan_perf *perf = static_cast<struct pan_perf *>(
|
||||
pan_driver.perf->get_subinstance());
|
||||
const auto counter =
|
||||
&perf->cfg->categories[gid].counters[id];
|
||||
return int64_t(pan_perf_counter_read(counter, perf));
|
||||
});
|
||||
|
||||
group.counters.push_back(cid++);
|
||||
|
||||
counters.emplace_back(counter);
|
||||
}
|
||||
|
||||
groups.push_back(group);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
PanfrostPerf::next()
|
||||
{
|
||||
auto ret = last_dump_ts;
|
||||
last_dump_ts = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PanfrostPerf::gpu_clock_id() const
|
||||
{
|
||||
return perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
PanfrostPerf::gpu_timestamp() const
|
||||
{
|
||||
return perfetto::base::GetBootTimeNs().count();
|
||||
}
|
||||
|
||||
bool
|
||||
PanfrostPerf::cpu_gpu_timestamp(uint64_t &, uint64_t &) const
|
||||
{
|
||||
/* Not supported */
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace pps
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <pps/pps.h>
|
||||
#include <pps/pps_counter.h>
|
||||
|
||||
struct pan_perf;
|
||||
|
||||
namespace pps {
|
||||
|
|
@ -27,17 +33,27 @@ class PanfrostPerf {
|
|||
PanfrostPerf(const PanfrostDevice &dev);
|
||||
~PanfrostPerf();
|
||||
|
||||
PanfrostPerf(const PanfrostPerf &) = delete;
|
||||
PanfrostPerf &operator=(const PanfrostPerf &) = delete;
|
||||
PanfrostPerf(PanfrostPerf &&o);
|
||||
PanfrostPerf &operator=(PanfrostPerf &&o);
|
||||
|
||||
PanfrostPerf(PanfrostPerf &&);
|
||||
PanfrostPerf &operator=(PanfrostPerf &&);
|
||||
std::pair<std::vector<CounterGroup>, std::vector<Counter>>
|
||||
create_available_counters() const;
|
||||
|
||||
int enable() const;
|
||||
void disable() const;
|
||||
int dump() const;
|
||||
uint64_t get_min_sampling_period_ns();
|
||||
bool init_perfcnt(int fd);
|
||||
int enable_perfcnt(uint64_t sampling_period_ns);
|
||||
void disable_perfcnt();
|
||||
bool dump_perfcnt();
|
||||
uint64_t next();
|
||||
uint32_t gpu_clock_id() const;
|
||||
uint64_t gpu_timestamp() const;
|
||||
bool cpu_gpu_timestamp(uint64_t &cpu_timestamp,
|
||||
uint64_t &gpu_timestamp) const;
|
||||
void *get_subinstance();
|
||||
|
||||
private:
|
||||
struct pan_perf *perf = nullptr;
|
||||
uint64_t last_dump_ts = 0;
|
||||
};
|
||||
|
||||
} // namespace pps
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue