132 lines
3.4 KiB
C++
132 lines
3.4 KiB
C++
/*
|
|
* Copyright © 2021 Google, Inc.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "pps/pps_driver.h"
|
|
|
|
#include "common/freedreno_dev_info.h"
|
|
#include "drm/freedreno_drmif.h"
|
|
#include "drm/freedreno_ringbuffer.h"
|
|
#include "perfcntrs/freedreno_dt.h"
|
|
#include "perfcntrs/freedreno_perfcntr.h"
|
|
|
|
namespace pps
|
|
{
|
|
|
|
class FreedrenoDriver : public Driver
|
|
{
|
|
public:
|
|
uint64_t get_min_sampling_period_ns() override;
|
|
bool init_perfcnt() override;
|
|
void enable_counter(uint32_t counter_id) override;
|
|
void enable_all_counters() override;
|
|
void enable_perfcnt(uint64_t sampling_period_ns) override;
|
|
void disable_perfcnt() override;
|
|
bool dump_perfcnt() override;
|
|
uint64_t next() override;
|
|
|
|
private:
|
|
struct fd_device *dev;
|
|
struct fd_pipe *pipe;
|
|
uint32_t gpu_id;
|
|
uint32_t max_freq;
|
|
uint32_t next_counter_id;
|
|
uint32_t next_countable_id;
|
|
uint64_t last_dump_ts = 0;
|
|
uint64_t last_capture_ts;
|
|
|
|
struct freedreno_dev_info info;
|
|
|
|
/**
|
|
* The memory mapped i/o space for counter readback:
|
|
*/
|
|
void *io;
|
|
|
|
const struct fd_perfcntr_group *perfcntrs;
|
|
unsigned num_perfcntrs;
|
|
|
|
/**
|
|
* The number of counters assigned per perfcntr group, the index
|
|
* into this matches the index into perfcntrs
|
|
*/
|
|
std::vector<int> assigned_counters;
|
|
|
|
/*
|
|
* Values that can be used by derived counters evaluation
|
|
*/
|
|
float time; /* time since last sample in fraction of second */
|
|
// uint32_t cycles; /* the number of clock cycles since last sample */
|
|
|
|
void setup_a6xx_counters();
|
|
|
|
void configure_counters(bool reset, bool wait);
|
|
void collect_countables();
|
|
|
|
/**
|
|
* Split out countable mutable state from the class so that copy-
|
|
* constructor does something sane when lambda derive function
|
|
* tries to get the countable value.
|
|
*/
|
|
struct CountableState {
|
|
uint64_t last_value, value;
|
|
const struct fd_perfcntr_countable *countable;
|
|
const struct fd_perfcntr_counter *counter;
|
|
};
|
|
|
|
std::vector<struct CountableState> state;
|
|
|
|
/**
|
|
* Performance counters on adreno consist of sets of counters in various
|
|
* blocks of the GPU, where each counter can be can be muxed to collect
|
|
* one of a set of countables.
|
|
*
|
|
* But the countables tend to be too low level to be directly useful to
|
|
* visualize. Instead various combinations of countables are combined
|
|
* with various formulas to derive the high level "Counter" value exposed
|
|
* via gfx-pps.
|
|
*
|
|
* This class serves to decouple the logic of those formulas from the
|
|
* details of collecting countable values.
|
|
*/
|
|
class Countable {
|
|
public:
|
|
Countable(FreedrenoDriver *d, std::string name);
|
|
|
|
operator int64_t() const { return get_value(); };
|
|
|
|
void configure(struct fd_ringbuffer *ring, bool reset);
|
|
void collect();
|
|
void resolve();
|
|
|
|
private:
|
|
|
|
uint64_t get_value() const;
|
|
|
|
uint32_t id;
|
|
FreedrenoDriver *d;
|
|
std::string name;
|
|
};
|
|
|
|
Countable countable(std::string name);
|
|
|
|
std::vector<Countable> countables;
|
|
|
|
/**
|
|
* A derived "Counter" (from pps's perspective)
|
|
*/
|
|
class DerivedCounter : public Counter {
|
|
public:
|
|
DerivedCounter(FreedrenoDriver *d, std::string name, Counter::Units units,
|
|
std::function<int64_t()> derive);
|
|
};
|
|
|
|
DerivedCounter counter(std::string name, Counter::Units units,
|
|
std::function<int64_t()> derive);
|
|
};
|
|
|
|
} // namespace pps
|