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
);
66 q
->funcs
->begin_query(fd_context(pctx
), q
);
72 fd_end_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
74 struct fd_query
*q
= fd_query(pq
);
76 /* there are a couple special cases, which don't have
77 * a matching ->begin_query():
79 if (skip_begin_query(q
->type
))
80 fd_begin_query(pctx
, pq
);
82 q
->funcs
->end_query(fd_context(pctx
), q
);
88 fd_get_query_result(struct pipe_context
*pctx
, struct pipe_query
*pq
,
89 bool wait
, union pipe_query_result
*result
)
91 struct fd_query
*q
= fd_query(pq
);
93 util_query_clear_result(result
, q
->type
);
95 return q
->funcs
->get_query_result(fd_context(pctx
), q
, wait
, result
);
99 fd_render_condition(struct pipe_context
*pctx
, struct pipe_query
*pq
,
100 bool condition
, enum pipe_render_cond_flag mode
)
102 struct fd_context
*ctx
= fd_context(pctx
);
103 ctx
->cond_query
= pq
;
104 ctx
->cond_cond
= condition
;
105 ctx
->cond_mode
= mode
;
108 #define _Q(_name, _query_type, _type, _result_type) { \
110 .query_type = _query_type, \
111 .type = PIPE_DRIVER_QUERY_TYPE_ ## _type, \
112 .result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_ ## _result_type, \
113 .group_id = ~(unsigned)0, \
116 #define FQ(_name, _query_type, _type, _result_type) \
117 _Q(_name, FD_QUERY_ ## _query_type, _type, _result_type)
119 #define PQ(_name, _query_type, _type, _result_type) \
120 _Q(_name, PIPE_QUERY_ ## _query_type, _type, _result_type)
122 static const struct pipe_driver_query_info sw_query_list
[] = {
123 FQ("draw-calls", DRAW_CALLS
, UINT64
, AVERAGE
),
124 FQ("batches", BATCH_TOTAL
, UINT64
, AVERAGE
),
125 FQ("batches-sysmem", BATCH_SYSMEM
, UINT64
, AVERAGE
),
126 FQ("batches-gmem", BATCH_GMEM
, UINT64
, AVERAGE
),
127 FQ("batches-nondraw", BATCH_NONDRAW
, UINT64
, AVERAGE
),
128 FQ("restores", BATCH_RESTORE
, UINT64
, AVERAGE
),
129 PQ("prims-emitted", PRIMITIVES_EMITTED
, UINT64
, AVERAGE
),
130 FQ("staging", STAGING_UPLOADS
, UINT64
, AVERAGE
),
131 FQ("shadow", SHADOW_UPLOADS
, UINT64
, AVERAGE
),
132 FQ("vsregs", VS_REGS
, FLOAT
, AVERAGE
),
133 FQ("fsregs", FS_REGS
, FLOAT
, AVERAGE
),
137 fd_get_driver_query_info(struct pipe_screen
*pscreen
,
138 unsigned index
, struct pipe_driver_query_info
*info
)
140 struct fd_screen
*screen
= fd_screen(pscreen
);
143 return ARRAY_SIZE(sw_query_list
) + screen
->num_perfcntr_queries
;
145 if (index
>= ARRAY_SIZE(sw_query_list
)) {
146 index
-= ARRAY_SIZE(sw_query_list
);
147 if (index
>= screen
->num_perfcntr_queries
)
149 *info
= screen
->perfcntr_queries
[index
];
153 *info
= sw_query_list
[index
];
158 fd_get_driver_query_group_info(struct pipe_screen
*pscreen
, unsigned index
,
159 struct pipe_driver_query_group_info
*info
)
161 struct fd_screen
*screen
= fd_screen(pscreen
);
164 return screen
->num_perfcntr_groups
;
166 if (index
>= screen
->num_perfcntr_groups
)
169 const struct fd_perfcntr_group
*g
= &screen
->perfcntr_groups
[index
];
171 info
->name
= g
->name
;
172 info
->max_active_queries
= g
->num_counters
;
173 info
->num_queries
= g
->num_countables
;
179 fd_set_active_query_state(struct pipe_context
*pctx
, bool enable
)
181 struct fd_context
*ctx
= fd_context(pctx
);
182 ctx
->active_queries
= enable
;
183 ctx
->update_active_queries
= true;
186 static enum pipe_driver_query_type
187 query_type(enum fd_perfcntr_type type
)
189 #define ENUM(t) case FD_PERFCNTR_ ## t: return PIPE_DRIVER_QUERY_ ## t
194 ENUM(TYPE_PERCENTAGE
);
196 ENUM(TYPE_MICROSECONDS
);
199 ENUM(TYPE_TEMPERATURE
);
204 unreachable("bad type");
209 static enum pipe_driver_query_result_type
210 query_result_type(enum fd_perfcntr_result_type type
)
213 ENUM(RESULT_TYPE_AVERAGE
);
214 ENUM(RESULT_TYPE_CUMULATIVE
);
216 unreachable("bad type");
222 setup_perfcntr_query_info(struct fd_screen
*screen
)
224 unsigned num_queries
= 0;
226 for (unsigned i
= 0; i
< screen
->num_perfcntr_groups
; i
++)
227 num_queries
+= screen
->perfcntr_groups
[i
].num_countables
;
229 screen
->perfcntr_queries
=
230 calloc(num_queries
, sizeof(screen
->perfcntr_queries
[0]));
231 screen
->num_perfcntr_queries
= num_queries
;
234 for (unsigned i
= 0; i
< screen
->num_perfcntr_groups
; i
++) {
235 const struct fd_perfcntr_group
*g
= &screen
->perfcntr_groups
[i
];
236 for (unsigned j
= 0; j
< g
->num_countables
; j
++) {
237 struct pipe_driver_query_info
*info
=
238 &screen
->perfcntr_queries
[idx
];
239 const struct fd_perfcntr_countable
*c
=
242 info
->name
= c
->name
;
243 info
->query_type
= FD_QUERY_FIRST_PERFCNTR
+ idx
;
244 info
->type
= query_type(c
->query_type
);
245 info
->result_type
= query_result_type(c
->result_type
);
247 info
->flags
= PIPE_DRIVER_QUERY_FLAG_BATCH
;
255 fd_query_screen_init(struct pipe_screen
*pscreen
)
257 pscreen
->get_driver_query_info
= fd_get_driver_query_info
;
258 pscreen
->get_driver_query_group_info
= fd_get_driver_query_group_info
;
259 setup_perfcntr_query_info(fd_screen(pscreen
));
263 fd_query_context_init(struct pipe_context
*pctx
)
265 pctx
->create_query
= fd_create_query
;
266 pctx
->destroy_query
= fd_destroy_query
;
267 pctx
->begin_query
= fd_begin_query
;
268 pctx
->end_query
= fd_end_query
;
269 pctx
->get_query_result
= fd_get_query_result
;
270 pctx
->set_active_query_state
= fd_set_active_query_state
;
271 pctx
->render_condition
= fd_render_condition
;