diff --git a/src/panfrost/ds/pan_pps_perf.cpp b/src/panfrost/ds/pan_pps_perf.cpp index 2f6ccbf0217..2a13a3a0088 100644 --- a/src/panfrost/ds/pan_pps_perf.cpp +++ b/src/panfrost/ds/pan_pps_perf.cpp @@ -1,5 +1,6 @@ /* * Copyright © 2021 Collabora, Ltd. + * Copyright © 2026 Arm, Ltd. * SPDX-License-Identifier: MIT */ @@ -86,39 +87,96 @@ PanfrostPerf::get_subinstance() { return perf; } +std::string +format_suffix(const char *fmt, uint8_t idx) +{ + assert(strlen(fmt) < 200 && "fmt unreasonably long"); + char buf[256]; + std::snprintf(buf, sizeof(buf), fmt, idx); + + return std::string(buf); +} + +const char * +get_block_suffix(uint8_t category) +{ + assert(category <= PAN_PERF_COUNTER_CAT_MAX); + + switch (category) { + case PAN_PERF_COUNTER_CAT_MEMSYS: + return " (slice %u)"; + case PAN_PERF_COUNTER_CAT_SHADER: + return " (core %u)"; + default: + return nullptr; + } + + return nullptr; +} + +Counter::Units +convert_pan_units(enum pan_perf_counter_units unit) +{ + switch (unit) { + case PAN_PERF_COUNTER_UNITS_PRIMITIVES: + return Counter::Units::Primitive; + case PAN_PERF_COUNTER_UNITS_INSTRUCTIONS: + return Counter::Units::Instruction; + case PAN_PERF_COUNTER_UNITS_BYTES: + return Counter::Units::Byte; + case PAN_PERF_COUNTER_UNITS_PIXELS: + return Counter::Units::Pixel; + default: + return Counter::Units::None; + } +} + std::pair, std::vector> PanfrostPerf::create_available_counters() const { std::pair, std::vector> ret; auto &[groups, counters] = ret; - size_t cid = 0; + uint32_t global_counter_id = 0; + + const struct pan_perf_category *category = NULL; + for (uint32_t cat_idx = 0; cat_idx < perf->cfg->n_categories; ++cat_idx) { + assert(cat_idx < PAN_PERF_COUNTER_CAT_MAX); + category = &perf->cfg->categories[cat_idx]; - 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; + group.id = cat_idx; + group.name = category->name; - for (size_t id = 0; cid < category.n_counters; ++cid) { - Counter counter = {}; - counter.id = cid; - counter.group = gid; + uint32_t n_blocks = perf->mem_layout.category[cat_idx].n_blocks; + for (uint32_t counter_idx = 0; counter_idx < category->n_counters; + ++counter_idx) { + const struct pan_perf_counter *cinfo = + &category->counters[counter_idx]; - counter.name = category.counters[id].name; + for (uint32_t block_idx = 0; block_idx < n_blocks; ++block_idx) { + const char *suffix = get_block_suffix(cat_idx); + const std::string name = + cinfo->name + (suffix ? format_suffix(suffix, block_idx) : ""); - counter.set_getter([=](const Counter &c, const Driver &d) { - auto &pan_driver = PanfrostDriver::into(d); - struct pan_perf *perf = static_cast( + Counter counter = {}; + counter.id = global_counter_id++; + counter.name = name; + counter.group = group.id; + counter.units = convert_pan_units(cinfo->units); + + 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)); - }); + return pan_perf_counter_read_raw( + perf, (enum pan_perf_counter_categories)cat_idx, block_idx, + cinfo->offset); + }); - group.counters.push_back(cid++); - - counters.emplace_back(counter); + group.counters.push_back(counter.id); + counters.emplace_back(counter); + } } groups.push_back(group);