Commit b80d7350 authored by Corentin Noël's avatar Corentin Noël
Browse files

gpu/intel: Allow to select a different metric set



Allow to use any metric set exposed by the driver, only one metric set can
be selected at a time so don't allow to mix the counters from different sets.

Keep the sane default to RenderBasic when "all counters" are requested.
Signed-off-by: Corentin Noël's avatarCorentin Noël <corentin.noel@collabora.com>
Reviewed-by: Antonio Caggiano's avatarAntonio Caggiano <antonio.caggiano@collabora.com>
parent a4aa2fd9
Pipeline #282404 passed with stages
in 3 minutes and 37 seconds
/*
* Copyright © 2020-2021 Collabora, Ltd.
* Author: Antonio Caggiano <antonio.caggiano@collabora.com>
* Author: Corentin Noël <corentin.noel@collabora.com>
*
* SPDX-License-Identifier: MIT
*/
......@@ -81,17 +82,7 @@ IntelDriver::~IntelDriver()
}
}
void IntelDriver::enable_counter(uint32_t counter_id)
{
// @todo enable counters selectively
}
void IntelDriver::enable_all_counters()
{
enabled_counters = counters;
}
intel_perf_metric_set *query_metric_set_by_name(const intel_perf &perf,
static intel_perf_metric_set *query_metric_set_by_name(const intel_perf &perf,
const std::string &metric_set)
{
intel_perf_metric_set *it = nullptr;
......@@ -108,62 +99,43 @@ intel_perf_metric_set *query_metric_set_by_name(const intel_perf &perf,
return ret;
}
/// @return A pair of a list of counter groups and a list of counters
std::pair<std::vector<CounterGroup>, std::vector<Counter>> query_counters(
const intel_perf_metric_set &metric_set)
void IntelDriver::enable_counter(uint32_t counter_id)
{
std::pair<std::vector<CounterGroup>, std::vector<Counter>> ret = {};
auto &groups = ret.first;
auto &counters = ret.second;
// Create group
CounterGroup group = {};
group.id = groups.size();
group.name = metric_set.symbol_name;
for (int i = 0; i < metric_set.n_counters; ++i) {
intel_perf_logical_counter &counter = metric_set.counters[i];
// Create counter
Counter counter_desc = {};
counter_desc.id = counters.size();
counter_desc.name = counter.symbol_name;
counter_desc.group = group.id;
counter_desc.getter = [counter, metric_set](
const Counter &c, const Driver &dri) -> Counter::Value {
auto &intel = reinterpret_cast<const IntelDriver &>(dri);
switch (counter.storage) {
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_UINT64:
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_UINT32:
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_BOOL32:
return (int64_t)counter.read_uint64(
intel.perf, &metric_set, const_cast<uint64_t *>(intel.accu.deltas));
break;
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_DOUBLE:
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_FLOAT:
return counter.read_float(
intel.perf, &metric_set, const_cast<uint64_t *>(intel.accu.deltas));
break;
}
return {};
};
// Add counter id to the group
group.counters.emplace_back(counter_desc.id);
auto &counter = counters[counter_id];
auto &group = groups[counter.group];
if (metric_set != nullptr) {
if (metric_set->symbol_name != group.name) {
PPS_LOG_ERROR("Unable to enable metrics from different sets: %u "
"belongs to %s but %s is currently in use.",
counter_id,
metric_set->symbol_name,
group.name.c_str());
return;
}
}
// Store counter
counters.emplace_back(std::move(counter_desc));
enabled_counters.emplace_back(counter);
if (metric_set == nullptr) {
metric_set = query_metric_set_by_name(*perf, group.name);
}
}
// Store group
groups.emplace_back(std::move(group));
void IntelDriver::enable_all_counters()
{
// We can only enable one metric set at a time so at least enable one.
for (auto &group : groups) {
if (group.name == "RenderBasic") {
for (uint32_t counter_id : group.counters) {
auto &counter = counters[counter_id];
enabled_counters.emplace_back(counter);
}
return ret;
metric_set = query_metric_set_by_name(*perf, group.name);
}
}
}
int perf_ioctl(int fd, unsigned long request, void *arg)
static int perf_ioctl(int fd, unsigned long request, void *arg)
{
int ret;
......@@ -174,7 +146,7 @@ int perf_ioctl(int fd, unsigned long request, void *arg)
return ret;
}
uint64_t timespec_diff(timespec *begin, timespec *end)
static uint64_t timespec_diff(timespec *begin, timespec *end)
{
return 1000000000ull * (end->tv_sec - begin->tv_sec) + end->tv_nsec - begin->tv_nsec;
}
......@@ -227,7 +199,7 @@ IntelDriver::query_correlation_timestamps() const
return corr;
}
uint64_t query_timestamp_frequency(const DrmDevice &drm_device)
static uint64_t query_timestamp_frequency(const DrmDevice &drm_device)
{
int timestamp_frequency;
......@@ -253,16 +225,55 @@ bool IntelDriver::init_perfcnt()
}
intel_perf_load_perf_configs(perf, drm_device.fd);
// Find RenderBasic metric set
const char *metric_set_name = "RenderBasic";
metric_set = query_metric_set_by_name(*perf, metric_set_name);
if (!metric_set) {
PPS_LOG_ERROR("Failed to find metric set %s", metric_set_name);
return false;
// Find groups and counters
intel_perf_metric_set *metric_set = nullptr;
igt_list_for_each_entry(metric_set, &perf->metric_sets, link) {
// Create group
CounterGroup group = {};
group.id = groups.size();
group.name = metric_set->symbol_name;
auto first_counter_id = counters.size();
for (int i = 0; i < metric_set->n_counters; ++i) {
intel_perf_logical_counter &counter = metric_set->counters[i];
// Create counter
Counter counter_desc = {};
counter_desc.id = counters.size();
counter_desc.name = counter.symbol_name;
counter_desc.group = group.id;
counter_desc.getter = [counter, metric_set](
const Counter &c, const Driver &dri) -> Counter::Value {
auto &intel = reinterpret_cast<const IntelDriver &>(dri);
switch (counter.storage) {
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_UINT64:
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_UINT32:
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_BOOL32:
return (int64_t)counter.read_uint64(
intel.perf, metric_set, const_cast<uint64_t *>(intel.accu.deltas));
break;
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_DOUBLE:
case INTEL_PERF_LOGICAL_COUNTER_STORAGE_FLOAT:
return counter.read_float(
intel.perf, metric_set, const_cast<uint64_t *>(intel.accu.deltas));
break;
}
return {};
};
// Add counter id to the group
group.counters.emplace_back(counter_desc.id);
// Store counter
counters.emplace_back(std::move(counter_desc));
}
PPS_LOG("Metric set %s: [%lu:%lu]", metric_set->symbol_name, first_counter_id, counters.size()-1);
// Store group
groups.emplace_back(std::move(group));
}
// Find groups and counters for this metric set
std::tie(groups, counters) = query_counters(*metric_set);
assert(groups.size() && "Failed to query groups");
assert(counters.size() && "Failed to query counters");
......@@ -483,7 +494,7 @@ struct Report {
};
/// @brief Adds accumulation src to dst
void add(const intel_perf_accumulator &src, intel_perf_accumulator &dest)
static void add(const intel_perf_accumulator &src, intel_perf_accumulator &dest)
{
const size_t delta_count = sizeof(dest.deltas) / sizeof(dest.deltas[0]);
for (size_t i = 0; i < delta_count; ++i) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment