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