1 /* 2 * Copyright © 2021 Google, Inc. 3 * SPDX-License-Identifier: MIT 4 */ 5 6 #pragma once 7 8 #include "pps/pps_driver.h" 9 10 extern "C" { 11 struct fd_dev_id; 12 struct fd_dev_info; 13 struct fd_device; 14 struct fd_pipe; 15 struct fd_ringbuffer; 16 struct fd_perfcntr_group; 17 struct fd_perfcntr_countable; 18 struct fd_perfcntr_counter; 19 }; 20 21 namespace pps 22 { 23 24 class FreedrenoDriver : public Driver 25 { 26 public: 27 bool is_dump_perfcnt_preemptible() const override; 28 uint64_t get_min_sampling_period_ns() override; 29 bool init_perfcnt() override; 30 void enable_counter(uint32_t counter_id) override; 31 void enable_all_counters() override; 32 void enable_perfcnt(uint64_t sampling_period_ns) override; 33 void disable_perfcnt() override; 34 bool dump_perfcnt() override; 35 uint64_t next() override; 36 uint32_t gpu_clock_id() const override; 37 uint64_t gpu_timestamp() const override; 38 bool cpu_gpu_timestamp(uint64_t &cpu_timestamp, 39 uint64_t &gpu_timestamp) const override; 40 41 private: 42 struct fd_device *dev; 43 struct fd_pipe *pipe; 44 const struct fd_dev_id *dev_id; 45 uint32_t max_freq; 46 uint32_t next_counter_id; 47 uint32_t next_countable_id; 48 uint64_t last_dump_ts = 0; 49 uint64_t last_capture_ts; 50 51 bool has_suspend_count; 52 uint32_t suspend_count; 53 54 const struct fd_dev_info *info; 55 56 /** 57 * The memory mapped i/o space for counter readback: 58 */ 59 void *io; 60 61 const struct fd_perfcntr_group *perfcntrs; 62 unsigned num_perfcntrs; 63 64 /** 65 * The number of counters assigned per perfcntr group, the index 66 * into this matches the index into perfcntrs 67 */ 68 std::vector<unsigned> assigned_counters; 69 70 /* 71 * Values that can be used by derived counters evaluation 72 */ 73 float time; /* time since last sample in fraction of second */ 74 // uint32_t cycles; /* the number of clock cycles since last sample */ 75 76 void setup_a6xx_counters(); 77 void setup_a7xx_counters(); 78 79 void configure_counters(bool reset, bool wait); 80 void collect_countables(); 81 82 /** 83 * Split out countable mutable state from the class so that copy- 84 * constructor does something sane when lambda derive function 85 * tries to get the countable value. 86 */ 87 struct CountableState { 88 uint64_t last_value, value; 89 const struct fd_perfcntr_countable *countable; 90 const struct fd_perfcntr_counter *counter; 91 }; 92 93 std::vector<struct CountableState> state; 94 95 /** 96 * Performance counters on adreno consist of sets of counters in various 97 * blocks of the GPU, where each counter can be can be muxed to collect 98 * one of a set of countables. 99 * 100 * But the countables tend to be too low level to be directly useful to 101 * visualize. Instead various combinations of countables are combined 102 * with various formulas to derive the high level "Counter" value exposed 103 * via gfx-pps. 104 * 105 * This class serves to decouple the logic of those formulas from the 106 * details of collecting countable values. 107 */ 108 class Countable { 109 public: 110 Countable(FreedrenoDriver *d, std::string group, std::string name); 111 int64_t()112 operator int64_t() const { return get_value(); }; 113 114 void configure(struct fd_ringbuffer *ring, bool reset) const; 115 void collect() const; 116 void resolve() const; 117 118 private: 119 120 uint64_t get_value() const; 121 122 uint32_t id; 123 FreedrenoDriver *d; 124 std::string group; 125 std::string name; 126 }; 127 128 Countable countable(std::string group, std::string name); 129 130 std::vector<Countable> countables; 131 132 /** 133 * A derived "Counter" (from pps's perspective) 134 */ 135 class DerivedCounter : public Counter { 136 public: 137 DerivedCounter(FreedrenoDriver *d, std::string name, Counter::Units units, 138 std::function<int64_t()> derive); 139 }; 140 141 DerivedCounter counter(std::string name, Counter::Units units, 142 std::function<int64_t()> derive); 143 }; 144 145 } // namespace pps 146