etnaviv: Rework resource status tracking
[mesa.git] / src / gallium / drivers / etnaviv / etnaviv_query_pm.c
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 "util/u_inlines.h"
29 #include "util/u_memory.h"
30
31 #include "etnaviv_context.h"
32 #include "etnaviv_query_pm.h"
33 #include "etnaviv_screen.h"
34
35 struct etna_perfmon_source
36 {
37 const char *domain;
38 const char *signal;
39 };
40
41 struct etna_perfmon_config
42 {
43 const char *name;
44 unsigned type;
45 unsigned group_id;
46 const struct etna_perfmon_source *source;
47 };
48
49 static const char *group_names[] = {
50 [ETNA_QUERY_HI_GROUP_ID] = "HI",
51 [ETNA_QUERY_PE_GROUP_ID] = "PE",
52 [ETNA_QUERY_SH_GROUP_ID] = "SH",
53 [ETNA_QUERY_PA_GROUP_ID] = "PA",
54 [ETNA_QUERY_SE_GROUP_ID] = "SE",
55 [ETNA_QUERY_RA_GROUP_ID] = "RA",
56 [ETNA_QUERY_TX_GROUP_ID] = "TX",
57 [ETNA_QUERY_MC_GROUP_ID] = "MC",
58 };
59
60 static const struct etna_perfmon_config query_config[] = {
61 {
62 .name = "hi-total-cycles",
63 .type = ETNA_QUERY_HI_TOTAL_CYCLES,
64 .group_id = ETNA_QUERY_HI_GROUP_ID,
65 .source = (const struct etna_perfmon_source[]) {
66 { "HI", "TOTAL_CYCLES" }
67 }
68 },
69 {
70 .name = "hi-idle-cycles",
71 .type = ETNA_QUERY_HI_IDLE_CYCLES,
72 .group_id = ETNA_QUERY_HI_GROUP_ID,
73 .source = (const struct etna_perfmon_source[]) {
74 { "HI", "IDLE_CYCLES" }
75 }
76 },
77 {
78 .name = "hi-axi-cycles-read-request-stalled",
79 .type = ETNA_QUERY_HI_AXI_CYCLES_READ_REQUEST_STALLED,
80 .group_id = ETNA_QUERY_HI_GROUP_ID,
81 .source = (const struct etna_perfmon_source[]) {
82 { "HI", "AXI_CYCLES_READ_REQUEST_STALLED" }
83 }
84 },
85 {
86 .name = "hi-axi-cycles-write-request-stalled",
87 .type = ETNA_QUERY_HI_AXI_CYCLES_WRITE_REQUEST_STALLED,
88 .group_id = ETNA_QUERY_HI_GROUP_ID,
89 .source = (const struct etna_perfmon_source[]) {
90 { "HI", "AXI_CYCLES_WRITE_REQUEST_STALLED" }
91 }
92 },
93 {
94 .name = "hi-axi-cycles-write-data-stalled",
95 .type = ETNA_QUERY_HI_AXI_CYCLES_WRITE_DATA_STALLED,
96 .group_id = ETNA_QUERY_HI_GROUP_ID,
97 .source = (const struct etna_perfmon_source[]) {
98 { "HI", "AXI_CYCLES_WRITE_DATA_STALLED" }
99 }
100 },
101 {
102 .name = "pe-pixel-count-killed-by-color-pipe",
103 .type = ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE,
104 .group_id = ETNA_QUERY_PE_GROUP_ID,
105 .source = (const struct etna_perfmon_source[]) {
106 { "PE", "PIXEL_COUNT_KILLED_BY_COLOR_PIPE" }
107 }
108 },
109 {
110 .name = "pe-pixel-count-killed-by-depth-pipe",
111 .type = ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE,
112 .group_id = ETNA_QUERY_PE_GROUP_ID,
113 .source = (const struct etna_perfmon_source[]) {
114 { "PE", "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE" }
115 }
116 },
117 {
118 .name = "pe-pixel-count-drawn-by-color-pipe",
119 .type = ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE,
120 .group_id = ETNA_QUERY_PE_GROUP_ID,
121 .source = (const struct etna_perfmon_source[]) {
122 { "PE", "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE" }
123 }
124 },
125 {
126 .name = "pe-pixel-count-drawn-by-depth-pipe",
127 .type = ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE,
128 .group_id = ETNA_QUERY_PE_GROUP_ID,
129 .source = (const struct etna_perfmon_source[]) {
130 { "PE", "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE" }
131 }
132 },
133 {
134 .name = "sh-shader-cycles",
135 .type = ETNA_QUERY_SH_SHADER_CYCLES,
136 .group_id = ETNA_QUERY_SH_GROUP_ID,
137 .source = (const struct etna_perfmon_source[]) {
138 { "SH", "SHADER_CYCLES" }
139 }
140 },
141 {
142 .name = "sh-ps-inst-counter",
143 .type = ETNA_QUERY_SH_PS_INST_COUNTER,
144 .group_id = ETNA_QUERY_SH_GROUP_ID,
145 .source = (const struct etna_perfmon_source[]) {
146 { "SH", "PS_INST_COUNTER" }
147 }
148 },
149 {
150 .name = "sh-rendered-pixel-counter",
151 .type = ETNA_QUERY_SH_RENDERED_PIXEL_COUNTER,
152 .group_id = ETNA_QUERY_SH_GROUP_ID,
153 .source = (const struct etna_perfmon_source[]) {
154 { "SH", "RENDERED_PIXEL_COUNTER" }
155 }
156 },
157 {
158 .name = "sh-vs-inst-counter",
159 .type = ETNA_QUERY_SH_VS_INST_COUNTER,
160 .group_id = ETNA_QUERY_SH_GROUP_ID,
161 .source = (const struct etna_perfmon_source[]) {
162 { "SH", "VS_INST_COUNTER" }
163 }
164 },
165 {
166 .name = "sh-rendered-vertice-counter",
167 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
168 .group_id = ETNA_QUERY_SH_GROUP_ID,
169 .source = (const struct etna_perfmon_source[]) {
170 { "SH", "RENDERED_VERTICE_COUNTER" }
171 }
172 },
173 {
174 .name = "sh-vtx-branch-inst-counter",
175 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
176 .group_id = ETNA_QUERY_SH_GROUP_ID,
177 .source = (const struct etna_perfmon_source[]) {
178 { "SH", "VTX_BRANCH_INST_COUNTER" }
179 }
180 },
181 {
182 .name = "sh-vtx-texld-inst-counter",
183 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
184 .group_id = ETNA_QUERY_SH_GROUP_ID,
185 .source = (const struct etna_perfmon_source[]) {
186 { "SH", "VTX_TEXLD_INST_COUNTER" }
187 }
188 },
189 {
190 .name = "sh-plx-branch-inst-counter",
191 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
192 .group_id = ETNA_QUERY_SH_GROUP_ID,
193 .source = (const struct etna_perfmon_source[]) {
194 { "SH", "PXL_BRANCH_INST_COUNTER" }
195 }
196 },
197 {
198 .name = "sh-plx-texld-inst-counter",
199 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
200 .group_id = ETNA_QUERY_SH_GROUP_ID,
201 .source = (const struct etna_perfmon_source[]) {
202 { "SH", "PXL_TEXLD_INST_COUNTER" }
203 }
204 },
205 {
206 .name = "pa-input-vtx-counter",
207 .type = ETNA_QUERY_PA_INPUT_VTX_COUNTER,
208 .group_id = ETNA_QUERY_PA_GROUP_ID,
209 .source = (const struct etna_perfmon_source[]) {
210 { "PA", "INPUT_VTX_COUNTER" }
211 }
212 },
213 {
214 .name = "pa-input-prim-counter",
215 .type = ETNA_QUERY_PA_INPUT_PRIM_COUNTER,
216 .group_id = ETNA_QUERY_PA_GROUP_ID,
217 .source = (const struct etna_perfmon_source[]) {
218 { "PA", "INPUT_PRIM_COUNTER" }
219 }
220 },
221 {
222 .name = "pa-output-prim-counter",
223 .type = ETNA_QUERY_PA_OUTPUT_PRIM_COUNTER,
224 .group_id = ETNA_QUERY_PA_GROUP_ID,
225 .source = (const struct etna_perfmon_source[]) {
226 { "PA", "OUTPUT_PRIM_COUNTER" }
227 }
228 },
229 {
230 .name = "pa-depth-clipped-counter",
231 .type = ETNA_QUERY_PA_DEPTH_CLIPPED_COUNTER,
232 .group_id = ETNA_QUERY_PA_GROUP_ID,
233 .source = (const struct etna_perfmon_source[]) {
234 { "PA", "DEPTH_CLIPPED_COUNTER" }
235 }
236 },
237 {
238 .name = "pa-trivial-rejected-counter",
239 .type = ETNA_QUERY_PA_TRIVIAL_REJECTED_COUNTER,
240 .group_id = ETNA_QUERY_PA_GROUP_ID,
241 .source = (const struct etna_perfmon_source[]) {
242 { "PA", "TRIVIAL_REJECTED_COUNTER" }
243 }
244 },
245 {
246 .name = "pa-culled-counter",
247 .type = ETNA_QUERY_PA_CULLED_COUNTER,
248 .group_id = ETNA_QUERY_PA_GROUP_ID,
249 .source = (const struct etna_perfmon_source[]) {
250 { "PA", "CULLED_COUNTER" }
251 }
252 },
253 {
254 .name = "se-culled-triangle-count",
255 .type = ETNA_QUERY_SE_CULLED_TRIANGLE_COUNT,
256 .group_id = ETNA_QUERY_SE_GROUP_ID,
257 .source = (const struct etna_perfmon_source[]) {
258 { "SE", "CULLED_TRIANGLE_COUNT" }
259 }
260 },
261 {
262 .name = "se-culled-lines-count",
263 .type = ETNA_QUERY_SE_CULLED_LINES_COUNT,
264 .group_id = ETNA_QUERY_SE_GROUP_ID,
265 .source = (const struct etna_perfmon_source[]) {
266 { "SE", "CULLED_LINES_COUNT" }
267 }
268 },
269 {
270 .name = "ra-valid-pixel-count",
271 .type = ETNA_QUERY_RA_VALID_PIXEL_COUNT,
272 .group_id = ETNA_QUERY_RA_GROUP_ID,
273 .source = (const struct etna_perfmon_source[]) {
274 { "RA", "VALID_PIXEL_COUNT" }
275 }
276 },
277 {
278 .name = "ra-total-quad-count",
279 .type = ETNA_QUERY_RA_TOTAL_QUAD_COUNT,
280 .group_id = ETNA_QUERY_RA_GROUP_ID,
281 .source = (const struct etna_perfmon_source[]) {
282 { "RA", "TOTAL_QUAD_COUNT" }
283 }
284 },
285 {
286 .name = "ra-valid-quad-count-after-early-z",
287 .type = ETNA_QUERY_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z,
288 .group_id = ETNA_QUERY_RA_GROUP_ID,
289 .source = (const struct etna_perfmon_source[]) {
290 { "RA", "VALID_QUAD_COUNT_AFTER_EARLY_Z" }
291 }
292 },
293 {
294 .name = "ra-total-primitive-count",
295 .type = ETNA_QUERY_RA_TOTAL_PRIMITIVE_COUNT,
296 .group_id = ETNA_QUERY_RA_GROUP_ID,
297 .source = (const struct etna_perfmon_source[]) {
298 { "RA", "TOTAL_PRIMITIVE_COUNT" }
299 }
300 },
301 {
302 .name = "ra-pipe-cache-miss-counter",
303 .type = ETNA_QUERY_RA_PIPE_CACHE_MISS_COUNTER,
304 .group_id = ETNA_QUERY_RA_GROUP_ID,
305 .source = (const struct etna_perfmon_source[]) {
306 { "RA", "PIPE_CACHE_MISS_COUNTER" }
307 }
308 },
309 {
310 .name = "ra-prefetch-cache-miss-counter",
311 .type = ETNA_QUERY_RA_PREFETCH_CACHE_MISS_COUNTER,
312 .group_id = ETNA_QUERY_RA_GROUP_ID,
313 .source = (const struct etna_perfmon_source[]) {
314 { "RA", "PREFETCH_CACHE_MISS_COUNTER" }
315 }
316 },
317 {
318 .name = "ra-pculled-quad-count",
319 .type = ETNA_QUERY_RA_CULLED_QUAD_COUNT,
320 .group_id = ETNA_QUERY_RA_GROUP_ID,
321 .source = (const struct etna_perfmon_source[]) {
322 { "RA", "CULLED_QUAD_COUNT" }
323 }
324 },
325 {
326 .name = "tx-total-bilinear-requests",
327 .type = ETNA_QUERY_TX_TOTAL_BILINEAR_REQUESTS,
328 .group_id = ETNA_QUERY_TX_GROUP_ID,
329 .source = (const struct etna_perfmon_source[]) {
330 { "TX", "TOTAL_BILINEAR_REQUESTS" }
331 }
332 },
333 {
334 .name = "tx-total-trilinear-requests",
335 .type = ETNA_QUERY_TX_TOTAL_TRILINEAR_REQUESTS,
336 .group_id = ETNA_QUERY_TX_GROUP_ID,
337 .source = (const struct etna_perfmon_source[]) {
338 { "TX", "TOTAL_TRILINEAR_REQUESTS" }
339 }
340 },
341 {
342 .name = "tx-total-discarded-texture-requests",
343 .type = ETNA_QUERY_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS,
344 .group_id = ETNA_QUERY_TX_GROUP_ID,
345 .source = (const struct etna_perfmon_source[]) {
346 { "TX", "TOTAL_DISCARDED_TEXTURE_REQUESTS" }
347 }
348 },
349 {
350 .name = "tx-total-texture-requests",
351 .type = ETNA_QUERY_TX_TOTAL_TEXTURE_REQUESTS,
352 .group_id = ETNA_QUERY_TX_GROUP_ID,
353 .source = (const struct etna_perfmon_source[]) {
354 { "TX", "TOTAL_TEXTURE_REQUESTS" }
355 }
356 },
357 {
358 .name = "tx-mem-read-count",
359 .type = ETNA_QUERY_TX_MEM_READ_COUNT,
360 .group_id = ETNA_QUERY_TX_GROUP_ID,
361 .source = (const struct etna_perfmon_source[]) {
362 { "TX", "MEM_READ_COUNT" }
363 }
364 },
365 {
366 .name = "tx-mem-read-in-8b-count",
367 .type = ETNA_QUERY_TX_MEM_READ_IN_8B_COUNT,
368 .group_id = ETNA_QUERY_TX_GROUP_ID,
369 .source = (const struct etna_perfmon_source[]) {
370 { "TX", "MEM_READ_IN_8B_COUNT" }
371 }
372 },
373 {
374 .name = "tx-cache-miss-count",
375 .type = ETNA_QUERY_TX_CACHE_MISS_COUNT,
376 .group_id = ETNA_QUERY_TX_GROUP_ID,
377 .source = (const struct etna_perfmon_source[]) {
378 { "TX", "CACHE_MISS_COUNT" }
379 }
380 },
381 {
382 .name = "tx-cache-hit-texel-count",
383 .type = ETNA_QUERY_TX_CACHE_HIT_TEXEL_COUNT,
384 .group_id = ETNA_QUERY_TX_GROUP_ID,
385 .source = (const struct etna_perfmon_source[]) {
386 { "TX", "CACHE_HIT_TEXEL_COUNT" }
387 }
388 },
389 {
390 .name = "tx-cache-miss-texel-count",
391 .type = ETNA_QUERY_TX_CACHE_MISS_TEXEL_COUNT,
392 .group_id = ETNA_QUERY_TX_GROUP_ID,
393 .source = (const struct etna_perfmon_source[]) {
394 { "TX", "CACHE_MISS_TEXEL_COUNT" }
395 }
396 },
397 {
398 .name = "mc-total-read-req-8b-from-pipeline",
399 .type = ETNA_QUERY_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE,
400 .group_id = ETNA_QUERY_MC_GROUP_ID,
401 .source = (const struct etna_perfmon_source[]) {
402 { "MC", "TOTAL_READ_REQ_8B_FROM_PIPELINE" }
403 }
404 },
405 {
406 .name = "mc-total-read-req-8b-from-ip",
407 .type = ETNA_QUERY_MC_TOTAL_READ_REQ_8B_FROM_IP,
408 .group_id = ETNA_QUERY_MC_GROUP_ID,
409 .source = (const struct etna_perfmon_source[]) {
410 { "MC", "TOTAL_READ_REQ_8B_FROM_IP" }
411 }
412 },
413 {
414 .name = "mc-total-write-req-8b-from-pipeline",
415 .type = ETNA_QUERY_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE,
416 .group_id = ETNA_QUERY_MC_GROUP_ID,
417 .source = (const struct etna_perfmon_source[]) {
418 { "MC", "TOTAL_WRITE_REQ_8B_FROM_PIPELINE" }
419 }
420 }
421 };
422
423 static const struct etna_perfmon_config *
424 etna_pm_query_config(unsigned type)
425 {
426 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++)
427 if (query_config[i].type == type)
428 return &query_config[i];
429
430 return NULL;
431 }
432
433 static struct etna_perfmon_signal *
434 etna_pm_query_signal(struct etna_perfmon *perfmon,
435 const struct etna_perfmon_source *source)
436 {
437 struct etna_perfmon_domain *domain;
438
439 domain = etna_perfmon_get_dom_by_name(perfmon, source->domain);
440 if (!domain)
441 return NULL;
442
443 return etna_perfmon_get_sig_by_name(domain, source->signal);
444 }
445
446 static inline bool
447 etna_pm_cfg_supported(struct etna_perfmon *perfmon,
448 const struct etna_perfmon_config *cfg)
449 {
450 struct etna_perfmon_signal *signal = etna_pm_query_signal(perfmon, cfg->source);
451
452 return !!signal;
453 }
454
455 static inline void
456 etna_pm_add_signal(struct etna_pm_query *pq, struct etna_perfmon *perfmon,
457 const struct etna_perfmon_config *cfg)
458 {
459 struct etna_perfmon_signal *signal = etna_pm_query_signal(perfmon, cfg->source);
460
461 pq->signal = signal;
462 }
463
464 static bool
465 realloc_query_bo(struct etna_context *ctx, struct etna_pm_query *pq)
466 {
467 if (pq->bo)
468 etna_bo_del(pq->bo);
469
470 pq->bo = etna_bo_new(ctx->screen->dev, 64, DRM_ETNA_GEM_CACHE_WC);
471 if (unlikely(!pq->bo))
472 return false;
473
474 pq->data = etna_bo_map(pq->bo);
475
476 return true;
477 }
478
479 static void
480 etna_pm_query_get(struct etna_cmd_stream *stream, struct etna_query *q,
481 unsigned flags)
482 {
483 struct etna_pm_query *pq = etna_pm_query(q);
484 unsigned offset;
485 assert(flags);
486
487 if (flags == ETNA_PM_PROCESS_PRE)
488 offset = 1;
489 else
490 offset = 2;
491
492 struct etna_perf p = {
493 .flags = flags,
494 .sequence = pq->sequence,
495 .bo = pq->bo,
496 .signal = pq->signal,
497 .offset = offset
498 };
499
500 etna_cmd_stream_perf(stream, &p);
501 }
502
503 static inline void
504 etna_pm_query_update(struct etna_query *q)
505 {
506 struct etna_pm_query *pq = etna_pm_query(q);
507
508 if (pq->data[0] == pq->sequence)
509 pq->ready = true;
510 }
511
512 static void
513 etna_pm_destroy_query(struct etna_context *ctx, struct etna_query *q)
514 {
515 struct etna_pm_query *pq = etna_pm_query(q);
516
517 etna_bo_del(pq->bo);
518 FREE(pq);
519 }
520
521 static bool
522 etna_pm_begin_query(struct etna_context *ctx, struct etna_query *q)
523 {
524 struct etna_pm_query *pq = etna_pm_query(q);
525
526 pq->ready = false;
527 pq->sequence++;
528
529 etna_pm_query_get(ctx->stream, q, ETNA_PM_PROCESS_PRE);
530
531 return true;
532 }
533
534 static void
535 etna_pm_end_query(struct etna_context *ctx, struct etna_query *q)
536 {
537 etna_pm_query_get(ctx->stream, q, ETNA_PM_PROCESS_POST);
538 }
539
540 static bool
541 etna_pm_get_query_result(struct etna_context *ctx, struct etna_query *q,
542 bool wait, union pipe_query_result *result)
543 {
544 struct etna_pm_query *pq = etna_pm_query(q);
545
546 etna_pm_query_update(q);
547
548 if (!pq->ready) {
549 if (!wait)
550 return false;
551
552 if (!etna_bo_cpu_prep(pq->bo, DRM_ETNA_PREP_READ))
553 return false;
554
555 pq->ready = true;
556 etna_bo_cpu_fini(pq->bo);
557 }
558
559 result->u32 = pq->data[2] - pq->data[1];
560
561 return true;
562 }
563
564 static const struct etna_query_funcs hw_query_funcs = {
565 .destroy_query = etna_pm_destroy_query,
566 .begin_query = etna_pm_begin_query,
567 .end_query = etna_pm_end_query,
568 .get_query_result = etna_pm_get_query_result,
569 };
570
571 struct etna_query *
572 etna_pm_create_query(struct etna_context *ctx, unsigned query_type)
573 {
574 struct etna_perfmon *perfmon = ctx->screen->perfmon;
575 const struct etna_perfmon_config *cfg;
576 struct etna_pm_query *pq;
577 struct etna_query *q;
578
579 cfg = etna_pm_query_config(query_type);
580 if (!cfg)
581 return NULL;
582
583 if (!etna_pm_cfg_supported(perfmon, cfg))
584 return NULL;
585
586 pq = CALLOC_STRUCT(etna_pm_query);
587 if (!pq)
588 return NULL;
589
590 if (!realloc_query_bo(ctx, pq)) {
591 FREE(pq);
592 return NULL;
593 }
594
595 q = &pq->base;
596 q->funcs = &hw_query_funcs;
597 q->type = query_type;
598
599 etna_pm_add_signal(pq, perfmon, cfg);
600
601 return q;
602 }
603
604 void
605 etna_pm_query_setup(struct etna_screen *screen)
606 {
607 screen->perfmon = etna_perfmon_create(screen->pipe);
608
609 if (!screen->perfmon)
610 return;
611
612 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++) {
613 const struct etna_perfmon_config *cfg = &query_config[i];
614
615 if (!etna_pm_cfg_supported(screen->perfmon, cfg))
616 continue;
617
618 util_dynarray_append(&screen->supported_pm_queries, unsigned, i);
619 }
620 }
621
622 int
623 etna_pm_get_driver_query_info(struct pipe_screen *pscreen, unsigned index,
624 struct pipe_driver_query_info *info)
625 {
626 const struct etna_screen *screen = etna_screen(pscreen);
627 const unsigned num = screen->supported_pm_queries.size / sizeof(unsigned);
628 unsigned i;
629
630 if (!info)
631 return num;
632
633 if (index >= num)
634 return 0;
635
636 i = *util_dynarray_element(&screen->supported_pm_queries, unsigned, index);
637 assert(i < ARRAY_SIZE(query_config));
638
639 info->name = query_config[i].name;
640 info->query_type = query_config[i].type;
641 info->group_id = query_config[i].group_id;
642 info->type = PIPE_DRIVER_QUERY_TYPE_UINT;
643 info->result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE;
644 info->max_value.u32 = 0;
645 info->flags = 0;
646
647 return 1;
648 }
649
650 static
651 unsigned query_count(unsigned group)
652 {
653 unsigned count = 0;
654
655 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++)
656 if (query_config[i].group_id == group)
657 count++;
658
659 assert(count);
660
661 return count;
662 }
663
664 int
665 etna_pm_get_driver_query_group_info(struct pipe_screen *pscreen,
666 unsigned index,
667 struct pipe_driver_query_group_info *info)
668 {
669 if (!info)
670 return ARRAY_SIZE(group_names);
671
672 if (index >= ARRAY_SIZE(group_names))
673 return 0;
674
675 unsigned count = query_count(index);
676
677 info->name = group_names[index];
678 info->max_active_queries = count;
679 info->num_queries = count;
680
681 return 1;
682 }