1 /************************************************************************** 2 * 3 * Copyright 2015 Alexander Trukhin 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 * 24 **************************************************************************/ 25 26 #pragma once 27 28 #include <memory> 29 #include <vector> 30 #include <map> 31 #include <string> 32 #include <queue> 33 34 #include "glproc.hpp" 35 #include "metric_backend.hpp" 36 #include "glretrace.hpp" 37 #include "mmap_allocator.hpp" 38 39 #define INTEL_NAME_LENGTH 256 // metric name with max 256 chars 40 #define INTEL_DESC_LENGTH 1024 // description max 1024 chars 41 42 class Metric_INTEL_perfquery : public Metric 43 { 44 private: 45 unsigned m_group, m_id; 46 unsigned m_offset; 47 std:: string m_name; 48 MetricNumType m_nType; 49 bool m_precached; 50 51 void precache(); 52 53 public: Metric_INTEL_perfquery(unsigned g,unsigned i)54 Metric_INTEL_perfquery(unsigned g, unsigned i) : m_group(g), m_id(i), 55 m_offset(0), 56 m_nType(CNT_NUM_UINT), 57 m_precached(false) {} 58 59 unsigned offset(); 60 61 62 unsigned id() override; 63 64 unsigned groupId() override; 65 66 std::string name() override; 67 68 std::string description() override; 69 70 MetricNumType numType() override; 71 72 MetricType type() override; 73 }; 74 75 76 class MetricBackend_INTEL_perfquery : public MetricBackend 77 { 78 private: 79 class DataCollector 80 { 81 private: 82 MmapAllocator<unsigned char> alloc; 83 // deque with custom allocator 84 template <class T> 85 using mmapdeque = std::deque<T, MmapAllocator<T>>; 86 // data storage 87 mmapdeque<mmapdeque<unsigned char*>> data; 88 unsigned curPass; 89 90 public: DataCollector(MmapAllocator<char> & alloc)91 DataCollector(MmapAllocator<char> &alloc) 92 : alloc(alloc), data(1, mmapdeque<unsigned char*>(alloc), alloc), 93 curPass(0) {} 94 95 ~DataCollector(); 96 97 unsigned char* newDataBuffer(unsigned event, size_t size); 98 99 void endPass(); 100 101 unsigned char* getDataBuffer(unsigned pass, unsigned event); 102 }; 103 104 private: 105 // map from query id to its Metric list 106 std::map<unsigned, std::vector<Metric_INTEL_perfquery>> passes[2]; 107 /* curQueryMetrics -- iterator through passes */ 108 std::map<unsigned, std::vector<Metric_INTEL_perfquery>>::iterator curQueryMetrics; 109 unsigned curQuery; 110 bool supported; 111 bool perFrame; 112 bool queryInProgress; 113 int numPasses; 114 int numFramePasses; 115 int curPass; 116 unsigned curEvent; // Currently evaluated event 117 DataCollector collector; 118 /* nameLookup for querying metrics by name */ 119 static std::map<std::string, std::pair<unsigned, unsigned>> nameLookup; 120 121 MetricBackend_INTEL_perfquery(glretrace::Context* context, MmapAllocator<char> &alloc); 122 123 MetricBackend_INTEL_perfquery(MetricBackend_INTEL_perfquery const&) = delete; 124 125 void operator=(MetricBackend_INTEL_perfquery const&) = delete; 126 127 void freeQuery(unsigned event); // collect metrics data from the query 128 129 static void populateLookupGroups(unsigned group, int error, void* userData); 130 131 static void populateLookupMetrics(Metric* metric, int error, void* userData); 132 133 public: 134 bool isSupported() override; 135 136 void enumGroups(enumGroupsCallback callback, void* userData = nullptr) override; 137 138 void enumMetrics(unsigned group, enumMetricsCallback callback, 139 void* userData = nullptr) override; 140 141 std::unique_ptr<Metric> getMetricById(unsigned groupId, unsigned metricId) override; 142 143 std::unique_ptr<Metric> getMetricByName(std::string metricName) override; 144 145 std::string getGroupName(unsigned group) override; 146 147 int enableMetric(Metric* metric, QueryBoundary pollingRule = QUERY_BOUNDARY_DRAWCALL) override; 148 149 unsigned generatePasses() override; 150 151 void beginPass() override; 152 153 void endPass() override; 154 155 void pausePass() override; 156 157 void continuePass() override; 158 159 void beginQuery(QueryBoundary boundary = QUERY_BOUNDARY_DRAWCALL) override; 160 161 void endQuery(QueryBoundary boundary = QUERY_BOUNDARY_DRAWCALL) override; 162 163 void enumDataQueryId(unsigned id, enumDataCallback callback, 164 QueryBoundary boundary, 165 void* userData = nullptr) override; 166 167 unsigned getNumPasses() override; 168 169 static MetricBackend_INTEL_perfquery& getInstance(glretrace::Context* context, 170 MmapAllocator<char> &alloc); 171 }; 172 173