1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci * Authors: 24bf215546Sopenharmony_ci * Rob Clark <robclark@freedesktop.org> 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "pipe/p_state.h" 28bf215546Sopenharmony_ci#include "util/u_memory.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "freedreno_context.h" 31bf215546Sopenharmony_ci#include "freedreno_query.h" 32bf215546Sopenharmony_ci#include "freedreno_query_hw.h" 33bf215546Sopenharmony_ci#include "freedreno_query_sw.h" 34bf215546Sopenharmony_ci#include "freedreno_util.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci/* 37bf215546Sopenharmony_ci * Pipe Query interface: 38bf215546Sopenharmony_ci */ 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_cistatic struct pipe_query * 41bf215546Sopenharmony_cifd_create_query(struct pipe_context *pctx, unsigned query_type, unsigned index) 42bf215546Sopenharmony_ci{ 43bf215546Sopenharmony_ci struct fd_context *ctx = fd_context(pctx); 44bf215546Sopenharmony_ci struct fd_query *q = NULL; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci if (ctx->create_query) 47bf215546Sopenharmony_ci q = ctx->create_query(ctx, query_type, index); 48bf215546Sopenharmony_ci if (!q) 49bf215546Sopenharmony_ci q = fd_sw_create_query(ctx, query_type, index); 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci return (struct pipe_query *)q; 52bf215546Sopenharmony_ci} 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_cistatic void 55bf215546Sopenharmony_cifd_destroy_query(struct pipe_context *pctx, struct pipe_query *pq) in_dt 56bf215546Sopenharmony_ci{ 57bf215546Sopenharmony_ci struct fd_query *q = fd_query(pq); 58bf215546Sopenharmony_ci q->funcs->destroy_query(fd_context(pctx), q); 59bf215546Sopenharmony_ci} 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_cistatic bool 62bf215546Sopenharmony_cifd_begin_query(struct pipe_context *pctx, struct pipe_query *pq) in_dt 63bf215546Sopenharmony_ci{ 64bf215546Sopenharmony_ci struct fd_query *q = fd_query(pq); 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci q->funcs->begin_query(fd_context(pctx), q); 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci return true; 69bf215546Sopenharmony_ci} 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_cistatic bool 72bf215546Sopenharmony_cifd_end_query(struct pipe_context *pctx, struct pipe_query *pq) in_dt 73bf215546Sopenharmony_ci{ 74bf215546Sopenharmony_ci struct fd_query *q = fd_query(pq); 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci /* there are a couple special cases, which don't have 77bf215546Sopenharmony_ci * a matching ->begin_query(): 78bf215546Sopenharmony_ci */ 79bf215546Sopenharmony_ci if (skip_begin_query(q->type)) 80bf215546Sopenharmony_ci fd_begin_query(pctx, pq); 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci q->funcs->end_query(fd_context(pctx), q); 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci return true; 85bf215546Sopenharmony_ci} 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_cistatic bool 88bf215546Sopenharmony_cifd_get_query_result(struct pipe_context *pctx, struct pipe_query *pq, bool wait, 89bf215546Sopenharmony_ci union pipe_query_result *result) 90bf215546Sopenharmony_ci{ 91bf215546Sopenharmony_ci struct fd_query *q = fd_query(pq); 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci util_query_clear_result(result, q->type); 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci return q->funcs->get_query_result(fd_context(pctx), q, wait, result); 96bf215546Sopenharmony_ci} 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_cistatic void 99bf215546Sopenharmony_cifd_render_condition(struct pipe_context *pctx, struct pipe_query *pq, 100bf215546Sopenharmony_ci bool condition, enum pipe_render_cond_flag mode) in_dt 101bf215546Sopenharmony_ci{ 102bf215546Sopenharmony_ci struct fd_context *ctx = fd_context(pctx); 103bf215546Sopenharmony_ci ctx->cond_query = pq; 104bf215546Sopenharmony_ci ctx->cond_cond = condition; 105bf215546Sopenharmony_ci ctx->cond_mode = mode; 106bf215546Sopenharmony_ci} 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci#define _Q(_name, _query_type, _type, _result_type) { \ 109bf215546Sopenharmony_ci .name = _name, .query_type = _query_type, \ 110bf215546Sopenharmony_ci .type = PIPE_DRIVER_QUERY_TYPE_##_type, \ 111bf215546Sopenharmony_ci .result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_##_result_type, \ 112bf215546Sopenharmony_ci .group_id = ~(unsigned)0, \ 113bf215546Sopenharmony_ci } 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci#define FQ(_name, _query_type, _type, _result_type) \ 116bf215546Sopenharmony_ci _Q(_name, FD_QUERY_##_query_type, _type, _result_type) 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci#define PQ(_name, _query_type, _type, _result_type) \ 119bf215546Sopenharmony_ci _Q(_name, PIPE_QUERY_##_query_type, _type, _result_type) 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_cistatic const struct pipe_driver_query_info sw_query_list[] = { 122bf215546Sopenharmony_ci FQ("draw-calls", DRAW_CALLS, UINT64, AVERAGE), 123bf215546Sopenharmony_ci FQ("batches", BATCH_TOTAL, UINT64, AVERAGE), 124bf215546Sopenharmony_ci FQ("batches-sysmem", BATCH_SYSMEM, UINT64, AVERAGE), 125bf215546Sopenharmony_ci FQ("batches-gmem", BATCH_GMEM, UINT64, AVERAGE), 126bf215546Sopenharmony_ci FQ("batches-nondraw", BATCH_NONDRAW, UINT64, AVERAGE), 127bf215546Sopenharmony_ci FQ("restores", BATCH_RESTORE, UINT64, AVERAGE), 128bf215546Sopenharmony_ci PQ("prims-emitted", PRIMITIVES_EMITTED, UINT64, AVERAGE), 129bf215546Sopenharmony_ci FQ("staging", STAGING_UPLOADS, UINT64, AVERAGE), 130bf215546Sopenharmony_ci FQ("shadow", SHADOW_UPLOADS, UINT64, AVERAGE), 131bf215546Sopenharmony_ci FQ("vsregs", VS_REGS, FLOAT, AVERAGE), 132bf215546Sopenharmony_ci FQ("fsregs", FS_REGS, FLOAT, AVERAGE), 133bf215546Sopenharmony_ci}; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_cistatic int 136bf215546Sopenharmony_cifd_get_driver_query_info(struct pipe_screen *pscreen, unsigned index, 137bf215546Sopenharmony_ci struct pipe_driver_query_info *info) 138bf215546Sopenharmony_ci{ 139bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci if (!info) 142bf215546Sopenharmony_ci return ARRAY_SIZE(sw_query_list) + screen->num_perfcntr_queries; 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci if (index >= ARRAY_SIZE(sw_query_list)) { 145bf215546Sopenharmony_ci index -= ARRAY_SIZE(sw_query_list); 146bf215546Sopenharmony_ci if (index >= screen->num_perfcntr_queries) 147bf215546Sopenharmony_ci return 0; 148bf215546Sopenharmony_ci *info = screen->perfcntr_queries[index]; 149bf215546Sopenharmony_ci return 1; 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci *info = sw_query_list[index]; 153bf215546Sopenharmony_ci return 1; 154bf215546Sopenharmony_ci} 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_cistatic int 157bf215546Sopenharmony_cifd_get_driver_query_group_info(struct pipe_screen *pscreen, unsigned index, 158bf215546Sopenharmony_ci struct pipe_driver_query_group_info *info) 159bf215546Sopenharmony_ci{ 160bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci if (!info) 163bf215546Sopenharmony_ci return screen->num_perfcntr_groups; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci if (index >= screen->num_perfcntr_groups) 166bf215546Sopenharmony_ci return 0; 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci const struct fd_perfcntr_group *g = &screen->perfcntr_groups[index]; 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci info->name = g->name; 171bf215546Sopenharmony_ci info->max_active_queries = g->num_counters; 172bf215546Sopenharmony_ci info->num_queries = g->num_countables; 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci return 1; 175bf215546Sopenharmony_ci} 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_cistatic void 178bf215546Sopenharmony_cifd_set_active_query_state(struct pipe_context *pctx, bool enable) assert_dt 179bf215546Sopenharmony_ci{ 180bf215546Sopenharmony_ci struct fd_context *ctx = fd_context(pctx); 181bf215546Sopenharmony_ci ctx->active_queries = enable; 182bf215546Sopenharmony_ci ctx->update_active_queries = true; 183bf215546Sopenharmony_ci} 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_cistatic enum pipe_driver_query_type 186bf215546Sopenharmony_ciquery_type(enum fd_perfcntr_type type) 187bf215546Sopenharmony_ci{ 188bf215546Sopenharmony_ci#define ENUM(t) \ 189bf215546Sopenharmony_ci case FD_PERFCNTR_##t: \ 190bf215546Sopenharmony_ci return PIPE_DRIVER_QUERY_##t 191bf215546Sopenharmony_ci switch (type) { 192bf215546Sopenharmony_ci ENUM(TYPE_UINT64); 193bf215546Sopenharmony_ci ENUM(TYPE_UINT); 194bf215546Sopenharmony_ci ENUM(TYPE_FLOAT); 195bf215546Sopenharmony_ci ENUM(TYPE_PERCENTAGE); 196bf215546Sopenharmony_ci ENUM(TYPE_BYTES); 197bf215546Sopenharmony_ci ENUM(TYPE_MICROSECONDS); 198bf215546Sopenharmony_ci ENUM(TYPE_HZ); 199bf215546Sopenharmony_ci ENUM(TYPE_DBM); 200bf215546Sopenharmony_ci ENUM(TYPE_TEMPERATURE); 201bf215546Sopenharmony_ci ENUM(TYPE_VOLTS); 202bf215546Sopenharmony_ci ENUM(TYPE_AMPS); 203bf215546Sopenharmony_ci ENUM(TYPE_WATTS); 204bf215546Sopenharmony_ci default: 205bf215546Sopenharmony_ci unreachable("bad type"); 206bf215546Sopenharmony_ci return 0; 207bf215546Sopenharmony_ci } 208bf215546Sopenharmony_ci} 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_cistatic enum pipe_driver_query_result_type 211bf215546Sopenharmony_ciquery_result_type(enum fd_perfcntr_result_type type) 212bf215546Sopenharmony_ci{ 213bf215546Sopenharmony_ci switch (type) { 214bf215546Sopenharmony_ci ENUM(RESULT_TYPE_AVERAGE); 215bf215546Sopenharmony_ci ENUM(RESULT_TYPE_CUMULATIVE); 216bf215546Sopenharmony_ci default: 217bf215546Sopenharmony_ci unreachable("bad type"); 218bf215546Sopenharmony_ci return 0; 219bf215546Sopenharmony_ci } 220bf215546Sopenharmony_ci} 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_cistatic void 223bf215546Sopenharmony_cisetup_perfcntr_query_info(struct fd_screen *screen) 224bf215546Sopenharmony_ci{ 225bf215546Sopenharmony_ci unsigned num_queries = 0; 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci for (unsigned i = 0; i < screen->num_perfcntr_groups; i++) 228bf215546Sopenharmony_ci num_queries += screen->perfcntr_groups[i].num_countables; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci screen->perfcntr_queries = 231bf215546Sopenharmony_ci calloc(num_queries, sizeof(screen->perfcntr_queries[0])); 232bf215546Sopenharmony_ci screen->num_perfcntr_queries = num_queries; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci unsigned idx = 0; 235bf215546Sopenharmony_ci for (unsigned i = 0; i < screen->num_perfcntr_groups; i++) { 236bf215546Sopenharmony_ci const struct fd_perfcntr_group *g = &screen->perfcntr_groups[i]; 237bf215546Sopenharmony_ci for (unsigned j = 0; j < g->num_countables; j++) { 238bf215546Sopenharmony_ci struct pipe_driver_query_info *info = &screen->perfcntr_queries[idx]; 239bf215546Sopenharmony_ci const struct fd_perfcntr_countable *c = &g->countables[j]; 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci info->name = c->name; 242bf215546Sopenharmony_ci info->query_type = FD_QUERY_FIRST_PERFCNTR + idx; 243bf215546Sopenharmony_ci info->type = query_type(c->query_type); 244bf215546Sopenharmony_ci info->result_type = query_result_type(c->result_type); 245bf215546Sopenharmony_ci info->group_id = i; 246bf215546Sopenharmony_ci info->flags = PIPE_DRIVER_QUERY_FLAG_BATCH; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci idx++; 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci } 251bf215546Sopenharmony_ci} 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_civoid 254bf215546Sopenharmony_cifd_query_screen_init(struct pipe_screen *pscreen) 255bf215546Sopenharmony_ci{ 256bf215546Sopenharmony_ci pscreen->get_driver_query_info = fd_get_driver_query_info; 257bf215546Sopenharmony_ci pscreen->get_driver_query_group_info = fd_get_driver_query_group_info; 258bf215546Sopenharmony_ci setup_perfcntr_query_info(fd_screen(pscreen)); 259bf215546Sopenharmony_ci} 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_civoid 262bf215546Sopenharmony_cifd_query_context_init(struct pipe_context *pctx) 263bf215546Sopenharmony_ci{ 264bf215546Sopenharmony_ci pctx->create_query = fd_create_query; 265bf215546Sopenharmony_ci pctx->destroy_query = fd_destroy_query; 266bf215546Sopenharmony_ci pctx->begin_query = fd_begin_query; 267bf215546Sopenharmony_ci pctx->end_query = fd_end_query; 268bf215546Sopenharmony_ci pctx->get_query_result = fd_get_query_result; 269bf215546Sopenharmony_ci pctx->set_active_query_state = fd_set_active_query_state; 270bf215546Sopenharmony_ci pctx->render_condition = fd_render_condition; 271bf215546Sopenharmony_ci} 272