1 /*
2 * Copyright (c) 2017 Etnaviv Project
3 * Copyright (C) 2017 Zodiac Inflight Innovations
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Christian Gmeiner <christian.gmeiner@gmail.com>
26 */
27
28 #include "etnaviv_context.h"
29 #include "etnaviv_perfmon.h"
30 #include "etnaviv_screen.h"
31
32 static const char *group_names[] = {
33 [ETNA_QUERY_HI_GROUP_ID] = "HI",
34 [ETNA_QUERY_PE_GROUP_ID] = "PE",
35 [ETNA_QUERY_SH_GROUP_ID] = "SH",
36 [ETNA_QUERY_PA_GROUP_ID] = "PA",
37 [ETNA_QUERY_SE_GROUP_ID] = "SE",
38 [ETNA_QUERY_RA_GROUP_ID] = "RA",
39 [ETNA_QUERY_TX_GROUP_ID] = "TX",
40 [ETNA_QUERY_MC_GROUP_ID] = "MC",
41 };
42
43 static const struct etna_perfmon_config query_config[] = {
44 {
45 .name = "hi-total-read-bytes",
46 .type = ETNA_QUERY_HI_TOTAL_READ_BYTES8,
47 .group_id = ETNA_QUERY_HI_GROUP_ID,
48 .source = (const struct etna_perfmon_source[]) {
49 { "HI", "TOTAL_READ_BYTES8" }
50 },
51 .multiply_with_8 = true
52 },
53 {
54 .name = "hi-total-write-bytes",
55 .type = ETNA_QUERY_HI_TOTAL_WRITE_BYTES8,
56 .group_id = ETNA_QUERY_HI_GROUP_ID,
57 .source = (const struct etna_perfmon_source[]) {
58 { "HI", "TOTAL_WRITE_BYTES8" }
59 },
60 .multiply_with_8 = true
61 },
62 {
63 .name = "hi-total-cycles",
64 .type = ETNA_QUERY_HI_TOTAL_CYCLES,
65 .group_id = ETNA_QUERY_HI_GROUP_ID,
66 .source = (const struct etna_perfmon_source[]) {
67 { "HI", "TOTAL_CYCLES" }
68 }
69 },
70 {
71 .name = "hi-idle-cycles",
72 .type = ETNA_QUERY_HI_IDLE_CYCLES,
73 .group_id = ETNA_QUERY_HI_GROUP_ID,
74 .source = (const struct etna_perfmon_source[]) {
75 { "HI", "IDLE_CYCLES" }
76 }
77 },
78 {
79 .name = "hi-axi-cycles-read-request-stalled",
80 .type = ETNA_QUERY_HI_AXI_CYCLES_READ_REQUEST_STALLED,
81 .group_id = ETNA_QUERY_HI_GROUP_ID,
82 .source = (const struct etna_perfmon_source[]) {
83 { "HI", "AXI_CYCLES_READ_REQUEST_STALLED" }
84 }
85 },
86 {
87 .name = "hi-axi-cycles-write-request-stalled",
88 .type = ETNA_QUERY_HI_AXI_CYCLES_WRITE_REQUEST_STALLED,
89 .group_id = ETNA_QUERY_HI_GROUP_ID,
90 .source = (const struct etna_perfmon_source[]) {
91 { "HI", "AXI_CYCLES_WRITE_REQUEST_STALLED" }
92 }
93 },
94 {
95 .name = "hi-axi-cycles-write-data-stalled",
96 .type = ETNA_QUERY_HI_AXI_CYCLES_WRITE_DATA_STALLED,
97 .group_id = ETNA_QUERY_HI_GROUP_ID,
98 .source = (const struct etna_perfmon_source[]) {
99 { "HI", "AXI_CYCLES_WRITE_DATA_STALLED" }
100 }
101 },
102 {
103 .name = "pe-pixel-count-killed-by-color-pipe",
104 .type = ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE,
105 .group_id = ETNA_QUERY_PE_GROUP_ID,
106 .source = (const struct etna_perfmon_source[]) {
107 { "PE", "PIXEL_COUNT_KILLED_BY_COLOR_PIPE" }
108 }
109 },
110 {
111 .name = "pe-pixel-count-killed-by-depth-pipe",
112 .type = ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE,
113 .group_id = ETNA_QUERY_PE_GROUP_ID,
114 .source = (const struct etna_perfmon_source[]) {
115 { "PE", "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE" }
116 }
117 },
118 {
119 .name = "pe-pixel-count-drawn-by-color-pipe",
120 .type = ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE,
121 .group_id = ETNA_QUERY_PE_GROUP_ID,
122 .source = (const struct etna_perfmon_source[]) {
123 { "PE", "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE" }
124 }
125 },
126 {
127 .name = "pe-pixel-count-drawn-by-depth-pipe",
128 .type = ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE,
129 .group_id = ETNA_QUERY_PE_GROUP_ID,
130 .source = (const struct etna_perfmon_source[]) {
131 { "PE", "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE" }
132 }
133 },
134 {
135 .name = "sh-shader-cycles",
136 .type = ETNA_QUERY_SH_SHADER_CYCLES,
137 .group_id = ETNA_QUERY_SH_GROUP_ID,
138 .source = (const struct etna_perfmon_source[]) {
139 { "SH", "SHADER_CYCLES" }
140 }
141 },
142 {
143 .name = "sh-ps-inst-counter",
144 .type = ETNA_QUERY_SH_PS_INST_COUNTER,
145 .group_id = ETNA_QUERY_SH_GROUP_ID,
146 .source = (const struct etna_perfmon_source[]) {
147 { "SH", "PS_INST_COUNTER" }
148 }
149 },
150 {
151 .name = "sh-rendered-pixel-counter",
152 .type = ETNA_QUERY_SH_RENDERED_PIXEL_COUNTER,
153 .group_id = ETNA_QUERY_SH_GROUP_ID,
154 .source = (const struct etna_perfmon_source[]) {
155 { "SH", "RENDERED_PIXEL_COUNTER" }
156 }
157 },
158 {
159 .name = "sh-vs-inst-counter",
160 .type = ETNA_QUERY_SH_VS_INST_COUNTER,
161 .group_id = ETNA_QUERY_SH_GROUP_ID,
162 .source = (const struct etna_perfmon_source[]) {
163 { "SH", "VS_INST_COUNTER" }
164 }
165 },
166 {
167 .name = "sh-rendered-vertice-counter",
168 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
169 .group_id = ETNA_QUERY_SH_GROUP_ID,
170 .source = (const struct etna_perfmon_source[]) {
171 { "SH", "RENDERED_VERTICE_COUNTER" }
172 }
173 },
174 {
175 .name = "sh-vtx-branch-inst-counter",
176 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
177 .group_id = ETNA_QUERY_SH_GROUP_ID,
178 .source = (const struct etna_perfmon_source[]) {
179 { "SH", "VTX_BRANCH_INST_COUNTER" }
180 }
181 },
182 {
183 .name = "sh-vtx-texld-inst-counter",
184 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
185 .group_id = ETNA_QUERY_SH_GROUP_ID,
186 .source = (const struct etna_perfmon_source[]) {
187 { "SH", "VTX_TEXLD_INST_COUNTER" }
188 }
189 },
190 {
191 .name = "sh-plx-branch-inst-counter",
192 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
193 .group_id = ETNA_QUERY_SH_GROUP_ID,
194 .source = (const struct etna_perfmon_source[]) {
195 { "SH", "PXL_BRANCH_INST_COUNTER" }
196 }
197 },
198 {
199 .name = "sh-plx-texld-inst-counter",
200 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
201 .group_id = ETNA_QUERY_SH_GROUP_ID,
202 .source = (const struct etna_perfmon_source[]) {
203 { "SH", "PXL_TEXLD_INST_COUNTER" }
204 }
205 },
206 {
207 .name = "pa-input-vtx-counter",
208 .type = ETNA_QUERY_PA_INPUT_VTX_COUNTER,
209 .group_id = ETNA_QUERY_PA_GROUP_ID,
210 .source = (const struct etna_perfmon_source[]) {
211 { "PA", "INPUT_VTX_COUNTER" }
212 }
213 },
214 {
215 .name = "pa-input-prim-counter",
216 .type = ETNA_QUERY_PA_INPUT_PRIM_COUNTER,
217 .group_id = ETNA_QUERY_PA_GROUP_ID,
218 .source = (const struct etna_perfmon_source[]) {
219 { "PA", "INPUT_PRIM_COUNTER" }
220 }
221 },
222 {
223 .name = "pa-output-prim-counter",
224 .type = ETNA_QUERY_PA_OUTPUT_PRIM_COUNTER,
225 .group_id = ETNA_QUERY_PA_GROUP_ID,
226 .source = (const struct etna_perfmon_source[]) {
227 { "PA", "OUTPUT_PRIM_COUNTER" }
228 }
229 },
230 {
231 .name = "pa-depth-clipped-counter",
232 .type = ETNA_QUERY_PA_DEPTH_CLIPPED_COUNTER,
233 .group_id = ETNA_QUERY_PA_GROUP_ID,
234 .source = (const struct etna_perfmon_source[]) {
235 { "PA", "DEPTH_CLIPPED_COUNTER" }
236 }
237 },
238 {
239 .name = "pa-trivial-rejected-counter",
240 .type = ETNA_QUERY_PA_TRIVIAL_REJECTED_COUNTER,
241 .group_id = ETNA_QUERY_PA_GROUP_ID,
242 .source = (const struct etna_perfmon_source[]) {
243 { "PA", "TRIVIAL_REJECTED_COUNTER" }
244 }
245 },
246 {
247 .name = "pa-culled-counter",
248 .type = ETNA_QUERY_PA_CULLED_COUNTER,
249 .group_id = ETNA_QUERY_PA_GROUP_ID,
250 .source = (const struct etna_perfmon_source[]) {
251 { "PA", "CULLED_COUNTER" }
252 }
253 },
254 {
255 .name = "se-culled-triangle-count",
256 .type = ETNA_QUERY_SE_CULLED_TRIANGLE_COUNT,
257 .group_id = ETNA_QUERY_SE_GROUP_ID,
258 .source = (const struct etna_perfmon_source[]) {
259 { "SE", "CULLED_TRIANGLE_COUNT" }
260 }
261 },
262 {
263 .name = "se-culled-lines-count",
264 .type = ETNA_QUERY_SE_CULLED_LINES_COUNT,
265 .group_id = ETNA_QUERY_SE_GROUP_ID,
266 .source = (const struct etna_perfmon_source[]) {
267 { "SE", "CULLED_LINES_COUNT" }
268 }
269 },
270 {
271 .name = "ra-valid-pixel-count",
272 .type = ETNA_QUERY_RA_VALID_PIXEL_COUNT,
273 .group_id = ETNA_QUERY_RA_GROUP_ID,
274 .source = (const struct etna_perfmon_source[]) {
275 { "RA", "VALID_PIXEL_COUNT" }
276 }
277 },
278 {
279 .name = "ra-total-quad-count",
280 .type = ETNA_QUERY_RA_TOTAL_QUAD_COUNT,
281 .group_id = ETNA_QUERY_RA_GROUP_ID,
282 .source = (const struct etna_perfmon_source[]) {
283 { "RA", "TOTAL_QUAD_COUNT" }
284 }
285 },
286 {
287 .name = "ra-valid-quad-count-after-early-z",
288 .type = ETNA_QUERY_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z,
289 .group_id = ETNA_QUERY_RA_GROUP_ID,
290 .source = (const struct etna_perfmon_source[]) {
291 { "RA", "VALID_QUAD_COUNT_AFTER_EARLY_Z" }
292 }
293 },
294 {
295 .name = "ra-total-primitive-count",
296 .type = ETNA_QUERY_RA_TOTAL_PRIMITIVE_COUNT,
297 .group_id = ETNA_QUERY_RA_GROUP_ID,
298 .source = (const struct etna_perfmon_source[]) {
299 { "RA", "TOTAL_PRIMITIVE_COUNT" }
300 }
301 },
302 {
303 .name = "ra-pipe-cache-miss-counter",
304 .type = ETNA_QUERY_RA_PIPE_CACHE_MISS_COUNTER,
305 .group_id = ETNA_QUERY_RA_GROUP_ID,
306 .source = (const struct etna_perfmon_source[]) {
307 { "RA", "PIPE_CACHE_MISS_COUNTER" }
308 }
309 },
310 {
311 .name = "ra-prefetch-cache-miss-counter",
312 .type = ETNA_QUERY_RA_PREFETCH_CACHE_MISS_COUNTER,
313 .group_id = ETNA_QUERY_RA_GROUP_ID,
314 .source = (const struct etna_perfmon_source[]) {
315 { "RA", "PREFETCH_CACHE_MISS_COUNTER" }
316 }
317 },
318 {
319 .name = "ra-pculled-quad-count",
320 .type = ETNA_QUERY_RA_CULLED_QUAD_COUNT,
321 .group_id = ETNA_QUERY_RA_GROUP_ID,
322 .source = (const struct etna_perfmon_source[]) {
323 { "RA", "CULLED_QUAD_COUNT" }
324 }
325 },
326 {
327 .name = "tx-total-bilinear-requests",
328 .type = ETNA_QUERY_TX_TOTAL_BILINEAR_REQUESTS,
329 .group_id = ETNA_QUERY_TX_GROUP_ID,
330 .source = (const struct etna_perfmon_source[]) {
331 { "TX", "TOTAL_BILINEAR_REQUESTS" }
332 }
333 },
334 {
335 .name = "tx-total-trilinear-requests",
336 .type = ETNA_QUERY_TX_TOTAL_TRILINEAR_REQUESTS,
337 .group_id = ETNA_QUERY_TX_GROUP_ID,
338 .source = (const struct etna_perfmon_source[]) {
339 { "TX", "TOTAL_TRILINEAR_REQUESTS" }
340 }
341 },
342 {
343 .name = "tx-total-discarded-texture-requests",
344 .type = ETNA_QUERY_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS,
345 .group_id = ETNA_QUERY_TX_GROUP_ID,
346 .source = (const struct etna_perfmon_source[]) {
347 { "TX", "TOTAL_DISCARDED_TEXTURE_REQUESTS" }
348 }
349 },
350 {
351 .name = "tx-total-texture-requests",
352 .type = ETNA_QUERY_TX_TOTAL_TEXTURE_REQUESTS,
353 .group_id = ETNA_QUERY_TX_GROUP_ID,
354 .source = (const struct etna_perfmon_source[]) {
355 { "TX", "TOTAL_TEXTURE_REQUESTS" }
356 }
357 },
358 {
359 .name = "tx-mem-read-count",
360 .type = ETNA_QUERY_TX_MEM_READ_COUNT,
361 .group_id = ETNA_QUERY_TX_GROUP_ID,
362 .source = (const struct etna_perfmon_source[]) {
363 { "TX", "MEM_READ_COUNT" }
364 }
365 },
366 {
367 .name = "tx-mem-read-bytes",
368 .type = ETNA_QUERY_TX_MEM_READ_IN_8B_COUNT,
369 .group_id = ETNA_QUERY_TX_GROUP_ID,
370 .source = (const struct etna_perfmon_source[]) {
371 { "TX", "MEM_READ_IN_8B_COUNT" }
372 },
373 .multiply_with_8 = true
374 },
375 {
376 .name = "tx-cache-miss-count",
377 .type = ETNA_QUERY_TX_CACHE_MISS_COUNT,
378 .group_id = ETNA_QUERY_TX_GROUP_ID,
379 .source = (const struct etna_perfmon_source[]) {
380 { "TX", "CACHE_MISS_COUNT" }
381 }
382 },
383 {
384 .name = "tx-cache-hit-texel-count",
385 .type = ETNA_QUERY_TX_CACHE_HIT_TEXEL_COUNT,
386 .group_id = ETNA_QUERY_TX_GROUP_ID,
387 .source = (const struct etna_perfmon_source[]) {
388 { "TX", "CACHE_HIT_TEXEL_COUNT" }
389 }
390 },
391 {
392 .name = "tx-cache-miss-texel-count",
393 .type = ETNA_QUERY_TX_CACHE_MISS_TEXEL_COUNT,
394 .group_id = ETNA_QUERY_TX_GROUP_ID,
395 .source = (const struct etna_perfmon_source[]) {
396 { "TX", "CACHE_MISS_TEXEL_COUNT" }
397 }
398 },
399 {
400 .name = "mc-total-read-req-8b-from-pipeline",
401 .type = ETNA_QUERY_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE,
402 .group_id = ETNA_QUERY_MC_GROUP_ID,
403 .source = (const struct etna_perfmon_source[]) {
404 { "MC", "TOTAL_READ_REQ_8B_FROM_PIPELINE" }
405 }
406 },
407 {
408 .name = "mc-total-read-req-8b-from-ip",
409 .type = ETNA_QUERY_MC_TOTAL_READ_REQ_8B_FROM_IP,
410 .group_id = ETNA_QUERY_MC_GROUP_ID,
411 .source = (const struct etna_perfmon_source[]) {
412 { "MC", "TOTAL_READ_REQ_8B_FROM_IP" }
413 }
414 },
415 {
416 .name = "mc-total-write-req-8b-from-pipeline",
417 .type = ETNA_QUERY_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE,
418 .group_id = ETNA_QUERY_MC_GROUP_ID,
419 .source = (const struct etna_perfmon_source[]) {
420 { "MC", "TOTAL_WRITE_REQ_8B_FROM_PIPELINE" }
421 }
422 }
423 };
424
425 struct etna_perfmon_signal *
etna_pm_query_signal(struct etna_perfmon * perfmon,const struct etna_perfmon_source * source)426 etna_pm_query_signal(struct etna_perfmon *perfmon,
427 const struct etna_perfmon_source *source)
428 {
429 struct etna_perfmon_domain *domain;
430
431 domain = etna_perfmon_get_dom_by_name(perfmon, source->domain);
432 if (!domain)
433 return NULL;
434
435 return etna_perfmon_get_sig_by_name(domain, source->signal);
436 }
437
438 void
etna_pm_query_setup(struct etna_screen * screen)439 etna_pm_query_setup(struct etna_screen *screen)
440 {
441 screen->perfmon = etna_perfmon_create(screen->pipe);
442
443 if (!screen->perfmon)
444 return;
445
446 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++) {
447 const struct etna_perfmon_config *cfg = &query_config[i];
448
449 if (!etna_pm_cfg_supported(screen->perfmon, cfg))
450 continue;
451
452 util_dynarray_append(&screen->supported_pm_queries, unsigned, i);
453 }
454 }
455
456 const struct etna_perfmon_config *
etna_pm_query_config(unsigned type)457 etna_pm_query_config(unsigned type)
458 {
459 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++)
460 if (query_config[i].type == type)
461 return &query_config[i];
462
463 return NULL;
464 }
465
466 int
etna_pm_get_driver_query_info(struct pipe_screen * pscreen,unsigned index,struct pipe_driver_query_info * info)467 etna_pm_get_driver_query_info(struct pipe_screen *pscreen, unsigned index,
468 struct pipe_driver_query_info *info)
469 {
470 const struct etna_screen *screen = etna_screen(pscreen);
471 const unsigned num = screen->supported_pm_queries.size / sizeof(unsigned);
472 unsigned i;
473
474 if (!info)
475 return num;
476
477 if (index >= num)
478 return 0;
479
480 i = *util_dynarray_element(&screen->supported_pm_queries, unsigned, index);
481 assert(i < ARRAY_SIZE(query_config));
482
483 info->name = query_config[i].name;
484 info->query_type = query_config[i].type;
485 info->group_id = query_config[i].group_id;
486
487 return 1;
488 }
489
490 static
query_count(unsigned group)491 unsigned query_count(unsigned group)
492 {
493 unsigned count = 0;
494
495 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++)
496 if (query_config[i].group_id == group)
497 count++;
498
499 assert(count);
500
501 return count;
502 }
503
504 int
etna_pm_get_driver_query_group_info(struct pipe_screen * pscreen,unsigned index,struct pipe_driver_query_group_info * info)505 etna_pm_get_driver_query_group_info(struct pipe_screen *pscreen,
506 unsigned index,
507 struct pipe_driver_query_group_info *info)
508 {
509 if (!info)
510 return ARRAY_SIZE(group_names);
511
512 if (index >= ARRAY_SIZE(group_names))
513 return 0;
514
515 unsigned count = query_count(index);
516
517 info->name = group_names[index];
518 info->max_active_queries = count;
519 info->num_queries = count;
520
521 return 1;
522 }
523