2 * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Rob Clark <robclark@freedesktop.org>
27 #include "pipe/p_state.h"
28 #include "util/u_memory.h"
30 #include "freedreno_query.h"
31 #include "freedreno_query_sw.h"
32 #include "freedreno_query_hw.h"
33 #include "freedreno_context.h"
34 #include "freedreno_util.h"
37 * Pipe Query interface:
40 static struct pipe_query
*
41 fd_create_query(struct pipe_context
*pctx
, unsigned query_type
, unsigned index
)
43 struct fd_context
*ctx
= fd_context(pctx
);
44 struct fd_query
*q
= NULL
;
46 if (ctx
->create_query
)
47 q
= ctx
->create_query(ctx
, query_type
, index
);
49 q
= fd_sw_create_query(ctx
, query_type
, index
);
51 return (struct pipe_query
*) q
;
55 fd_destroy_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
57 struct fd_query
*q
= fd_query(pq
);
58 q
->funcs
->destroy_query(fd_context(pctx
), q
);
62 fd_begin_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
64 struct fd_query
*q
= fd_query(pq
);
70 ret
= q
->funcs
->begin_query(fd_context(pctx
), q
);
77 fd_end_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
79 struct fd_query
*q
= fd_query(pq
);
81 /* there are a couple special cases, which don't have
82 * a matching ->begin_query():
84 if (skip_begin_query(q
->type
) && !q
->active
)
85 fd_begin_query(pctx
, pq
);
90 q
->funcs
->end_query(fd_context(pctx
), q
);
97 fd_get_query_result(struct pipe_context
*pctx
, struct pipe_query
*pq
,
98 bool wait
, union pipe_query_result
*result
)
100 struct fd_query
*q
= fd_query(pq
);
105 util_query_clear_result(result
, q
->type
);
107 return q
->funcs
->get_query_result(fd_context(pctx
), q
, wait
, result
);
111 fd_render_condition(struct pipe_context
*pctx
, struct pipe_query
*pq
,
112 bool condition
, enum pipe_render_cond_flag mode
)
114 struct fd_context
*ctx
= fd_context(pctx
);
115 ctx
->cond_query
= pq
;
116 ctx
->cond_cond
= condition
;
117 ctx
->cond_mode
= mode
;
120 #define _Q(_name, _query_type, _type, _result_type) { \
122 .query_type = _query_type, \
123 .type = PIPE_DRIVER_QUERY_TYPE_ ## _type, \
124 .result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_ ## _result_type, \
125 .group_id = ~(unsigned)0, \
128 #define FQ(_name, _query_type, _type, _result_type) \
129 _Q(_name, FD_QUERY_ ## _query_type, _type, _result_type)
131 #define PQ(_name, _query_type, _type, _result_type) \
132 _Q(_name, PIPE_QUERY_ ## _query_type, _type, _result_type)
134 static const struct pipe_driver_query_info sw_query_list
[] = {
135 FQ("draw-calls", DRAW_CALLS
, UINT64
, AVERAGE
),
136 FQ("batches", BATCH_TOTAL
, UINT64
, AVERAGE
),
137 FQ("batches-sysmem", BATCH_SYSMEM
, UINT64
, AVERAGE
),
138 FQ("batches-gmem", BATCH_GMEM
, UINT64
, AVERAGE
),
139 FQ("batches-nondraw", BATCH_NONDRAW
, UINT64
, AVERAGE
),
140 FQ("restores", BATCH_RESTORE
, UINT64
, AVERAGE
),
141 PQ("prims-emitted", PRIMITIVES_EMITTED
, UINT64
, AVERAGE
),
142 FQ("staging", STAGING_UPLOADS
, UINT64
, AVERAGE
),
143 FQ("shadow", SHADOW_UPLOADS
, UINT64
, AVERAGE
),
144 FQ("vsregs", VS_REGS
, FLOAT
, AVERAGE
),
145 FQ("fsregs", FS_REGS
, FLOAT
, AVERAGE
),
149 fd_get_driver_query_info(struct pipe_screen
*pscreen
,
150 unsigned index
, struct pipe_driver_query_info
*info
)
152 struct fd_screen
*screen
= fd_screen(pscreen
);
155 return ARRAY_SIZE(sw_query_list
) + screen
->num_perfcntr_queries
;
157 if (index
>= ARRAY_SIZE(sw_query_list
)) {
158 index
-= ARRAY_SIZE(sw_query_list
);
159 if (index
>= screen
->num_perfcntr_queries
)
161 *info
= screen
->perfcntr_queries
[index
];
165 *info
= sw_query_list
[index
];
170 fd_get_driver_query_group_info(struct pipe_screen
*pscreen
, unsigned index
,
171 struct pipe_driver_query_group_info
*info
)
173 struct fd_screen
*screen
= fd_screen(pscreen
);
176 return screen
->num_perfcntr_groups
;
178 if (index
>= screen
->num_perfcntr_groups
)
181 const struct fd_perfcntr_group
*g
= &screen
->perfcntr_groups
[index
];
183 info
->name
= g
->name
;
184 info
->max_active_queries
= g
->num_counters
;
185 info
->num_queries
= g
->num_countables
;
191 fd_set_active_query_state(struct pipe_context
*pipe
, bool enable
)
195 static enum pipe_driver_query_type
196 query_type(enum fd_perfcntr_type type
)
198 #define ENUM(t) case FD_PERFCNTR_ ## t: return PIPE_DRIVER_QUERY_ ## t
203 ENUM(TYPE_PERCENTAGE
);
205 ENUM(TYPE_MICROSECONDS
);
208 ENUM(TYPE_TEMPERATURE
);
213 unreachable("bad type");
218 static enum pipe_driver_query_result_type
219 query_result_type(enum fd_perfcntr_result_type type
)
222 ENUM(RESULT_TYPE_AVERAGE
);
223 ENUM(RESULT_TYPE_CUMULATIVE
);
225 unreachable("bad type");
231 setup_perfcntr_query_info(struct fd_screen
*screen
)
233 unsigned num_queries
= 0;
235 for (unsigned i
= 0; i
< screen
->num_perfcntr_groups
; i
++)
236 num_queries
+= screen
->perfcntr_groups
[i
].num_countables
;
238 screen
->perfcntr_queries
=
239 calloc(num_queries
, sizeof(screen
->perfcntr_queries
[0]));
240 screen
->num_perfcntr_queries
= num_queries
;
243 for (unsigned i
= 0; i
< screen
->num_perfcntr_groups
; i
++) {
244 const struct fd_perfcntr_group
*g
= &screen
->perfcntr_groups
[i
];
245 for (unsigned j
= 0; j
< g
->num_countables
; j
++) {
246 struct pipe_driver_query_info
*info
=
247 &screen
->perfcntr_queries
[idx
];
248 const struct fd_perfcntr_countable
*c
=
251 info
->name
= c
->name
;
252 info
->query_type
= FD_QUERY_FIRST_PERFCNTR
+ idx
;
253 info
->type
= query_type(c
->query_type
);
254 info
->result_type
= query_result_type(c
->result_type
);
256 info
->flags
= PIPE_DRIVER_QUERY_FLAG_BATCH
;
264 fd_query_screen_init(struct pipe_screen
*pscreen
)
266 pscreen
->get_driver_query_info
= fd_get_driver_query_info
;
267 pscreen
->get_driver_query_group_info
= fd_get_driver_query_group_info
;
268 setup_perfcntr_query_info(fd_screen(pscreen
));
272 fd_query_context_init(struct pipe_context
*pctx
)
274 pctx
->create_query
= fd_create_query
;
275 pctx
->destroy_query
= fd_destroy_query
;
276 pctx
->begin_query
= fd_begin_query
;
277 pctx
->end_query
= fd_end_query
;
278 pctx
->get_query_result
= fd_get_query_result
;
279 pctx
->set_active_query_state
= fd_set_active_query_state
;
280 pctx
->render_condition
= fd_render_condition
;