1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2013 Marek Olšák <maraeo@gmail.com> 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci/* This file contains code for reading values from pipe queries 29bf215546Sopenharmony_ci * for displaying on the HUD. To prevent stalls when reading queries, we 30bf215546Sopenharmony_ci * keep a list of busy queries in a ring. We read only those queries which 31bf215546Sopenharmony_ci * are idle. 32bf215546Sopenharmony_ci */ 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "hud/hud_private.h" 35bf215546Sopenharmony_ci#include "pipe/p_screen.h" 36bf215546Sopenharmony_ci#include "util/os_time.h" 37bf215546Sopenharmony_ci#include "util/u_math.h" 38bf215546Sopenharmony_ci#include "util/u_memory.h" 39bf215546Sopenharmony_ci#include <stdio.h> 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci// Must be a power of two 42bf215546Sopenharmony_ci#define NUM_QUERIES 8 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistruct hud_batch_query_context { 45bf215546Sopenharmony_ci unsigned num_query_types; 46bf215546Sopenharmony_ci unsigned allocated_query_types; 47bf215546Sopenharmony_ci unsigned *query_types; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci boolean failed; 50bf215546Sopenharmony_ci struct pipe_query *query[NUM_QUERIES]; 51bf215546Sopenharmony_ci union pipe_query_result *result[NUM_QUERIES]; 52bf215546Sopenharmony_ci unsigned head, pending, results; 53bf215546Sopenharmony_ci}; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_civoid 56bf215546Sopenharmony_cihud_batch_query_update(struct hud_batch_query_context *bq, 57bf215546Sopenharmony_ci struct pipe_context *pipe) 58bf215546Sopenharmony_ci{ 59bf215546Sopenharmony_ci if (!bq || bq->failed) 60bf215546Sopenharmony_ci return; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci if (bq->query[bq->head]) 63bf215546Sopenharmony_ci pipe->end_query(pipe, bq->query[bq->head]); 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci bq->results = 0; 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci while (bq->pending) { 68bf215546Sopenharmony_ci unsigned idx = (bq->head - bq->pending + 1) % NUM_QUERIES; 69bf215546Sopenharmony_ci struct pipe_query *query = bq->query[idx]; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci if (!bq->result[idx]) 72bf215546Sopenharmony_ci bq->result[idx] = MALLOC(sizeof(bq->result[idx]->batch[0]) * 73bf215546Sopenharmony_ci bq->num_query_types); 74bf215546Sopenharmony_ci if (!bq->result[idx]) { 75bf215546Sopenharmony_ci fprintf(stderr, "gallium_hud: out of memory.\n"); 76bf215546Sopenharmony_ci bq->failed = TRUE; 77bf215546Sopenharmony_ci return; 78bf215546Sopenharmony_ci } 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci if (!pipe->get_query_result(pipe, query, FALSE, bq->result[idx])) 81bf215546Sopenharmony_ci break; 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci ++bq->results; 84bf215546Sopenharmony_ci --bq->pending; 85bf215546Sopenharmony_ci } 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci bq->head = (bq->head + 1) % NUM_QUERIES; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci if (bq->pending == NUM_QUERIES) { 90bf215546Sopenharmony_ci fprintf(stderr, 91bf215546Sopenharmony_ci "gallium_hud: all queries busy after %i frames, dropping data.\n", 92bf215546Sopenharmony_ci NUM_QUERIES); 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci assert(bq->query[bq->head]); 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci pipe->destroy_query(pipe, bq->query[bq->head]); 97bf215546Sopenharmony_ci bq->query[bq->head] = NULL; 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci ++bq->pending; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci if (!bq->query[bq->head]) { 103bf215546Sopenharmony_ci bq->query[bq->head] = pipe->create_batch_query(pipe, 104bf215546Sopenharmony_ci bq->num_query_types, 105bf215546Sopenharmony_ci bq->query_types); 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci if (!bq->query[bq->head]) { 108bf215546Sopenharmony_ci fprintf(stderr, 109bf215546Sopenharmony_ci "gallium_hud: create_batch_query failed. You may have " 110bf215546Sopenharmony_ci "selected too many or incompatible queries.\n"); 111bf215546Sopenharmony_ci bq->failed = TRUE; 112bf215546Sopenharmony_ci return; 113bf215546Sopenharmony_ci } 114bf215546Sopenharmony_ci } 115bf215546Sopenharmony_ci} 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_civoid 118bf215546Sopenharmony_cihud_batch_query_begin(struct hud_batch_query_context *bq, 119bf215546Sopenharmony_ci struct pipe_context *pipe) 120bf215546Sopenharmony_ci{ 121bf215546Sopenharmony_ci if (!bq || bq->failed || !bq->query[bq->head]) 122bf215546Sopenharmony_ci return; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci if (!pipe->begin_query(pipe, bq->query[bq->head])) { 125bf215546Sopenharmony_ci fprintf(stderr, 126bf215546Sopenharmony_ci "gallium_hud: could not begin batch query. You may have " 127bf215546Sopenharmony_ci "selected too many or incompatible queries.\n"); 128bf215546Sopenharmony_ci bq->failed = TRUE; 129bf215546Sopenharmony_ci } 130bf215546Sopenharmony_ci} 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_cistatic boolean 133bf215546Sopenharmony_cibatch_query_add(struct hud_batch_query_context **pbq, 134bf215546Sopenharmony_ci unsigned query_type, unsigned *result_index) 135bf215546Sopenharmony_ci{ 136bf215546Sopenharmony_ci struct hud_batch_query_context *bq = *pbq; 137bf215546Sopenharmony_ci unsigned i; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci if (!bq) { 140bf215546Sopenharmony_ci bq = CALLOC_STRUCT(hud_batch_query_context); 141bf215546Sopenharmony_ci if (!bq) 142bf215546Sopenharmony_ci return false; 143bf215546Sopenharmony_ci *pbq = bq; 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci for (i = 0; i < bq->num_query_types; ++i) { 147bf215546Sopenharmony_ci if (bq->query_types[i] == query_type) { 148bf215546Sopenharmony_ci *result_index = i; 149bf215546Sopenharmony_ci return true; 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci if (bq->num_query_types == bq->allocated_query_types) { 154bf215546Sopenharmony_ci unsigned new_alloc = MAX2(16, bq->allocated_query_types * 2); 155bf215546Sopenharmony_ci unsigned *new_query_types 156bf215546Sopenharmony_ci = REALLOC(bq->query_types, 157bf215546Sopenharmony_ci bq->allocated_query_types * sizeof(unsigned), 158bf215546Sopenharmony_ci new_alloc * sizeof(unsigned)); 159bf215546Sopenharmony_ci if (!new_query_types) 160bf215546Sopenharmony_ci return false; 161bf215546Sopenharmony_ci bq->query_types = new_query_types; 162bf215546Sopenharmony_ci bq->allocated_query_types = new_alloc; 163bf215546Sopenharmony_ci } 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci bq->query_types[bq->num_query_types] = query_type; 166bf215546Sopenharmony_ci *result_index = bq->num_query_types++; 167bf215546Sopenharmony_ci return true; 168bf215546Sopenharmony_ci} 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_civoid 171bf215546Sopenharmony_cihud_batch_query_cleanup(struct hud_batch_query_context **pbq, 172bf215546Sopenharmony_ci struct pipe_context *pipe) 173bf215546Sopenharmony_ci{ 174bf215546Sopenharmony_ci struct hud_batch_query_context *bq = *pbq; 175bf215546Sopenharmony_ci unsigned idx; 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci if (!bq) 178bf215546Sopenharmony_ci return; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci *pbq = NULL; 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci if (bq->query[bq->head] && !bq->failed) 183bf215546Sopenharmony_ci pipe->end_query(pipe, bq->query[bq->head]); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci for (idx = 0; idx < NUM_QUERIES; ++idx) { 186bf215546Sopenharmony_ci if (bq->query[idx]) 187bf215546Sopenharmony_ci pipe->destroy_query(pipe, bq->query[idx]); 188bf215546Sopenharmony_ci FREE(bq->result[idx]); 189bf215546Sopenharmony_ci } 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci FREE(bq->query_types); 192bf215546Sopenharmony_ci FREE(bq); 193bf215546Sopenharmony_ci} 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_cistruct query_info { 196bf215546Sopenharmony_ci struct hud_batch_query_context *batch; 197bf215546Sopenharmony_ci enum pipe_query_type query_type; 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci /** index to choose fields in pipe_query_data_pipeline_statistics, 200bf215546Sopenharmony_ci * for example. 201bf215546Sopenharmony_ci */ 202bf215546Sopenharmony_ci unsigned result_index; 203bf215546Sopenharmony_ci enum pipe_driver_query_result_type result_type; 204bf215546Sopenharmony_ci enum pipe_driver_query_type type; 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci /* Ring of queries. If a query is busy, we use another slot. */ 207bf215546Sopenharmony_ci struct pipe_query *query[NUM_QUERIES]; 208bf215546Sopenharmony_ci unsigned head, tail; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci uint64_t last_time; 211bf215546Sopenharmony_ci uint64_t results_cumulative; 212bf215546Sopenharmony_ci unsigned num_results; 213bf215546Sopenharmony_ci}; 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_cistatic void 216bf215546Sopenharmony_ciquery_new_value_batch(struct query_info *info) 217bf215546Sopenharmony_ci{ 218bf215546Sopenharmony_ci struct hud_batch_query_context *bq = info->batch; 219bf215546Sopenharmony_ci unsigned result_index = info->result_index; 220bf215546Sopenharmony_ci unsigned idx = (bq->head - bq->pending) % NUM_QUERIES; 221bf215546Sopenharmony_ci unsigned results = bq->results; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci while (results) { 224bf215546Sopenharmony_ci info->results_cumulative += bq->result[idx]->batch[result_index].u64; 225bf215546Sopenharmony_ci ++info->num_results; 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci --results; 228bf215546Sopenharmony_ci idx = (idx - 1) % NUM_QUERIES; 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci} 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_cistatic void 233bf215546Sopenharmony_ciquery_new_value_normal(struct query_info *info, struct pipe_context *pipe) 234bf215546Sopenharmony_ci{ 235bf215546Sopenharmony_ci if (info->last_time) { 236bf215546Sopenharmony_ci if (info->query[info->head]) 237bf215546Sopenharmony_ci pipe->end_query(pipe, info->query[info->head]); 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci /* read query results */ 240bf215546Sopenharmony_ci while (1) { 241bf215546Sopenharmony_ci struct pipe_query *query = info->query[info->tail]; 242bf215546Sopenharmony_ci union pipe_query_result result; 243bf215546Sopenharmony_ci uint64_t *res64 = (uint64_t *)&result; 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci if (query && pipe->get_query_result(pipe, query, FALSE, &result)) { 246bf215546Sopenharmony_ci if (info->type == PIPE_DRIVER_QUERY_TYPE_FLOAT) { 247bf215546Sopenharmony_ci assert(info->result_index == 0); 248bf215546Sopenharmony_ci info->results_cumulative += (uint64_t) (result.f * 1000.0f); 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci else { 251bf215546Sopenharmony_ci info->results_cumulative += res64[info->result_index]; 252bf215546Sopenharmony_ci } 253bf215546Sopenharmony_ci info->num_results++; 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci if (info->tail == info->head) 256bf215546Sopenharmony_ci break; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci info->tail = (info->tail+1) % NUM_QUERIES; 259bf215546Sopenharmony_ci } 260bf215546Sopenharmony_ci else { 261bf215546Sopenharmony_ci /* the oldest query is busy */ 262bf215546Sopenharmony_ci if ((info->head+1) % NUM_QUERIES == info->tail) { 263bf215546Sopenharmony_ci /* all queries are busy, throw away the last query and create 264bf215546Sopenharmony_ci * a new one */ 265bf215546Sopenharmony_ci fprintf(stderr, 266bf215546Sopenharmony_ci "gallium_hud: all queries are busy after %i frames, " 267bf215546Sopenharmony_ci "can't add another query\n", 268bf215546Sopenharmony_ci NUM_QUERIES); 269bf215546Sopenharmony_ci if (info->query[info->head]) 270bf215546Sopenharmony_ci pipe->destroy_query(pipe, info->query[info->head]); 271bf215546Sopenharmony_ci info->query[info->head] = 272bf215546Sopenharmony_ci pipe->create_query(pipe, info->query_type, 0); 273bf215546Sopenharmony_ci } 274bf215546Sopenharmony_ci else { 275bf215546Sopenharmony_ci /* the last query is busy, we need to add a new one we can use 276bf215546Sopenharmony_ci * for this frame */ 277bf215546Sopenharmony_ci info->head = (info->head+1) % NUM_QUERIES; 278bf215546Sopenharmony_ci if (!info->query[info->head]) { 279bf215546Sopenharmony_ci info->query[info->head] = 280bf215546Sopenharmony_ci pipe->create_query(pipe, info->query_type, 0); 281bf215546Sopenharmony_ci } 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci break; 284bf215546Sopenharmony_ci } 285bf215546Sopenharmony_ci } 286bf215546Sopenharmony_ci } 287bf215546Sopenharmony_ci else { 288bf215546Sopenharmony_ci /* initialize */ 289bf215546Sopenharmony_ci info->query[info->head] = pipe->create_query(pipe, info->query_type, 0); 290bf215546Sopenharmony_ci } 291bf215546Sopenharmony_ci} 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_cistatic void 294bf215546Sopenharmony_cibegin_query(struct hud_graph *gr, struct pipe_context *pipe) 295bf215546Sopenharmony_ci{ 296bf215546Sopenharmony_ci struct query_info *info = gr->query_data; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci assert(!info->batch); 299bf215546Sopenharmony_ci if (info->query[info->head]) 300bf215546Sopenharmony_ci pipe->begin_query(pipe, info->query[info->head]); 301bf215546Sopenharmony_ci} 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_cistatic void 304bf215546Sopenharmony_ciquery_new_value(struct hud_graph *gr, struct pipe_context *pipe) 305bf215546Sopenharmony_ci{ 306bf215546Sopenharmony_ci struct query_info *info = gr->query_data; 307bf215546Sopenharmony_ci uint64_t now = os_time_get(); 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci if (info->batch) { 310bf215546Sopenharmony_ci query_new_value_batch(info); 311bf215546Sopenharmony_ci } else { 312bf215546Sopenharmony_ci query_new_value_normal(info, pipe); 313bf215546Sopenharmony_ci } 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci if (!info->last_time) { 316bf215546Sopenharmony_ci info->last_time = now; 317bf215546Sopenharmony_ci return; 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci if (info->num_results && info->last_time + gr->pane->period <= now) { 321bf215546Sopenharmony_ci double value; 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci switch (info->result_type) { 324bf215546Sopenharmony_ci default: 325bf215546Sopenharmony_ci case PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE: 326bf215546Sopenharmony_ci value = info->results_cumulative / info->num_results; 327bf215546Sopenharmony_ci break; 328bf215546Sopenharmony_ci case PIPE_DRIVER_QUERY_RESULT_TYPE_CUMULATIVE: 329bf215546Sopenharmony_ci value = info->results_cumulative; 330bf215546Sopenharmony_ci break; 331bf215546Sopenharmony_ci } 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci if (info->type == PIPE_DRIVER_QUERY_TYPE_FLOAT) { 334bf215546Sopenharmony_ci value /= 1000.0; 335bf215546Sopenharmony_ci } 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci hud_graph_add_value(gr, value); 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci info->last_time = now; 340bf215546Sopenharmony_ci info->results_cumulative = 0; 341bf215546Sopenharmony_ci info->num_results = 0; 342bf215546Sopenharmony_ci } 343bf215546Sopenharmony_ci} 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_cistatic void 346bf215546Sopenharmony_cifree_query_info(void *ptr, struct pipe_context *pipe) 347bf215546Sopenharmony_ci{ 348bf215546Sopenharmony_ci struct query_info *info = ptr; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci if (!info->batch && info->last_time) { 351bf215546Sopenharmony_ci int i; 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci pipe->end_query(pipe, info->query[info->head]); 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(info->query); i++) { 356bf215546Sopenharmony_ci if (info->query[i]) { 357bf215546Sopenharmony_ci pipe->destroy_query(pipe, info->query[i]); 358bf215546Sopenharmony_ci } 359bf215546Sopenharmony_ci } 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci FREE(info); 362bf215546Sopenharmony_ci} 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci/** 366bf215546Sopenharmony_ci * \param result_index to select fields of pipe_query_data_pipeline_statistics, 367bf215546Sopenharmony_ci * for example. 368bf215546Sopenharmony_ci */ 369bf215546Sopenharmony_civoid 370bf215546Sopenharmony_cihud_pipe_query_install(struct hud_batch_query_context **pbq, 371bf215546Sopenharmony_ci struct hud_pane *pane, 372bf215546Sopenharmony_ci const char *name, 373bf215546Sopenharmony_ci enum pipe_query_type query_type, 374bf215546Sopenharmony_ci unsigned result_index, 375bf215546Sopenharmony_ci uint64_t max_value, enum pipe_driver_query_type type, 376bf215546Sopenharmony_ci enum pipe_driver_query_result_type result_type, 377bf215546Sopenharmony_ci unsigned flags) 378bf215546Sopenharmony_ci{ 379bf215546Sopenharmony_ci struct hud_graph *gr; 380bf215546Sopenharmony_ci struct query_info *info; 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci gr = CALLOC_STRUCT(hud_graph); 383bf215546Sopenharmony_ci if (!gr) 384bf215546Sopenharmony_ci return; 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci strncpy(gr->name, name, sizeof(gr->name)); 387bf215546Sopenharmony_ci gr->name[sizeof(gr->name) - 1] = '\0'; 388bf215546Sopenharmony_ci gr->query_data = CALLOC_STRUCT(query_info); 389bf215546Sopenharmony_ci if (!gr->query_data) 390bf215546Sopenharmony_ci goto fail_gr; 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci gr->query_new_value = query_new_value; 393bf215546Sopenharmony_ci gr->free_query_data = free_query_info; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci info = gr->query_data; 396bf215546Sopenharmony_ci info->result_type = result_type; 397bf215546Sopenharmony_ci info->type = type; 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci if (flags & PIPE_DRIVER_QUERY_FLAG_BATCH) { 400bf215546Sopenharmony_ci if (!batch_query_add(pbq, query_type, &info->result_index)) 401bf215546Sopenharmony_ci goto fail_info; 402bf215546Sopenharmony_ci info->batch = *pbq; 403bf215546Sopenharmony_ci } else { 404bf215546Sopenharmony_ci gr->begin_query = begin_query; 405bf215546Sopenharmony_ci info->query_type = query_type; 406bf215546Sopenharmony_ci info->result_index = result_index; 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci hud_pane_add_graph(pane, gr); 410bf215546Sopenharmony_ci pane->type = type; /* must be set before updating the max_value */ 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci if (pane->max_value < max_value) 413bf215546Sopenharmony_ci hud_pane_set_max_value(pane, max_value); 414bf215546Sopenharmony_ci return; 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_cifail_info: 417bf215546Sopenharmony_ci FREE(info); 418bf215546Sopenharmony_cifail_gr: 419bf215546Sopenharmony_ci FREE(gr); 420bf215546Sopenharmony_ci} 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ciboolean 423bf215546Sopenharmony_cihud_driver_query_install(struct hud_batch_query_context **pbq, 424bf215546Sopenharmony_ci struct hud_pane *pane, struct pipe_screen *screen, 425bf215546Sopenharmony_ci const char *name) 426bf215546Sopenharmony_ci{ 427bf215546Sopenharmony_ci struct pipe_driver_query_info query = { 0 }; 428bf215546Sopenharmony_ci unsigned num_queries, i; 429bf215546Sopenharmony_ci boolean found = FALSE; 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci if (!screen->get_driver_query_info) 432bf215546Sopenharmony_ci return FALSE; 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci num_queries = screen->get_driver_query_info(screen, 0, NULL); 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci for (i = 0; i < num_queries; i++) { 437bf215546Sopenharmony_ci if (screen->get_driver_query_info(screen, i, &query) && 438bf215546Sopenharmony_ci strcmp(query.name, name) == 0) { 439bf215546Sopenharmony_ci found = TRUE; 440bf215546Sopenharmony_ci break; 441bf215546Sopenharmony_ci } 442bf215546Sopenharmony_ci } 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_ci if (!found) 445bf215546Sopenharmony_ci return FALSE; 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci hud_pipe_query_install(pbq, pane, query.name, query.query_type, 0, 448bf215546Sopenharmony_ci query.max_value.u64, query.type, query.result_type, 449bf215546Sopenharmony_ci query.flags); 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci return TRUE; 452bf215546Sopenharmony_ci} 453