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 78 void configure_counters(bool reset, bool wait); 79 void collect_countables(); 80 81 /** 82 * Split out countable mutable state from the class so that copy- 83 * constructor does something sane when lambda derive function 84 * tries to get the countable value. 85 */ 86 struct CountableState { 87 uint64_t last_value, value; 88 const struct fd_perfcntr_countable *countable; 89 const struct fd_perfcntr_counter *counter; 90 }; 91 92 std::vector<struct CountableState> state; 93 94 /** 95 * Performance counters on adreno consist of sets of counters in various 96 * blocks of the GPU, where each counter can be can be muxed to collect 97 * one of a set of countables. 98 * 99 * But the countables tend to be too low level to be directly useful to 100 * visualize. Instead various combinations of countables are combined 101 * with various formulas to derive the high level "Counter" value exposed 102 * via gfx-pps. 103 * 104 * This class serves to decouple the logic of those formulas from the 105 * details of collecting countable values. 106 */ 107 class Countable { 108 public: 109 Countable(FreedrenoDriver *d, std::string name); 110 int64_t()111 operator int64_t() const { return get_value(); }; 112 113 void configure(struct fd_ringbuffer *ring, bool reset) const; 114 void collect() const; 115 void resolve() const; 116 117 private: 118 119 uint64_t get_value() const; 120 121 uint32_t id; 122 FreedrenoDriver *d; 123 std::string name; 124 }; 125 126 Countable countable(std::string name); 127 128 std::vector<Countable> countables; 129 130 /** 131 * A derived "Counter" (from pps's perspective) 132 */ 133 class DerivedCounter : public Counter { 134 public: 135 DerivedCounter(FreedrenoDriver *d, std::string name, Counter::Units units, 136 std::function<int64_t()> derive); 137 }; 138 139 DerivedCounter counter(std::string name, Counter::Units units, 140 std::function<int64_t()> derive); 141 }; 142 143 } // namespace pps 144