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 35struct etna_perfmon_source 36{ 37 const char *domain; 38 const char *signal; 39}; 40 41struct etna_perfmon_config 42{ 43 const char *name; 44 unsigned type; 45 unsigned group_id; 46 const struct etna_perfmon_source *source; 47}; 48 49static 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 60static 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 423static const struct etna_perfmon_config * 424etna_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 433static struct etna_perfmon_signal * 434etna_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 446static inline bool 447etna_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 455static inline void 456etna_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 464static bool 465realloc_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 479static void 480etna_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 = 2; 489 else 490 offset = 3; 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 503static inline void 504etna_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 512static void 513etna_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 521static boolean 522etna_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 534static void 535etna_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 540static boolean 541etna_pm_get_query_result(struct etna_context *ctx, struct etna_query *q, 542 boolean 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 564static 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 571struct etna_query * 572etna_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 604void 605etna_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 622int 623etna_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 643 return 1; 644} 645 646static 647unsigned query_count(unsigned group) 648{ 649 unsigned count = 0; 650 651 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++) 652 if (query_config[i].group_id == group) 653 count++; 654 655 assert(count); 656 657 return count; 658} 659 660int 661etna_pm_get_driver_query_group_info(struct pipe_screen *pscreen, 662 unsigned index, 663 struct pipe_driver_query_group_info *info) 664{ 665 if (!info) 666 return ARRAY_SIZE(group_names); 667 668 if (index >= ARRAY_SIZE(group_names)) 669 return 0; 670 671 unsigned count = query_count(index); 672 673 info->name = group_names[index]; 674 info->max_active_queries = count; 675 info->num_queries = count; 676 677 return 1; 678} 679