diff --git a/src/panfrost/ds/pan_pps_driver.cpp b/src/panfrost/ds/pan_pps_driver.cpp index f5982a0cba6..aa752777611 100644 --- a/src/panfrost/ds/pan_pps_driver.cpp +++ b/src/panfrost/ds/pan_pps_driver.cpp @@ -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> PanfrostDriver::create_available_counters(const PanfrostPerf &perf) { - std::pair, std::vector> 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(drm_device.fd); } + if (!perf) { perf = std::make_unique(*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 diff --git a/src/panfrost/ds/pan_pps_perf.cpp b/src/panfrost/ds/pan_pps_perf.cpp index f801779c18e..2f6ccbf0217 100644 --- a/src/panfrost/ds/pan_pps_perf.cpp +++ b/src/panfrost/ds/pan_pps_perf.cpp @@ -4,6 +4,7 @@ */ #include "pan_pps_perf.h" +#include "pan_pps_driver.h" #include #include @@ -12,14 +13,12 @@ #include namespace pps { - PanfrostPerf::PanfrostPerf(const PanfrostDevice &dev) - : perf{reinterpret_cast( - rzalloc(nullptr, struct pan_perf))} { + perf = reinterpret_cast( + 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> +PanfrostPerf::create_available_counters() const +{ + std::pair, std::vector> 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( + 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 diff --git a/src/panfrost/ds/pan_pps_perf.h b/src/panfrost/ds/pan_pps_perf.h index 742f1aa8f44..b07df750ccb 100644 --- a/src/panfrost/ds/pan_pps_perf.h +++ b/src/panfrost/ds/pan_pps_perf.h @@ -5,6 +5,12 @@ #pragma once +#include +#include +#include +#include +#include + 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> + 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