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
);
46 q
= fd_sw_create_query(ctx
, query_type
);
47 if (!q
&& ctx
->create_query
)
48 q
= ctx
->create_query(ctx
, query_type
);
50 return (struct pipe_query
*) q
;
54 fd_destroy_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
56 struct fd_query
*q
= fd_query(pq
);
57 q
->funcs
->destroy_query(fd_context(pctx
), q
);
61 fd_begin_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
63 struct fd_query
*q
= fd_query(pq
);
69 ret
= q
->funcs
->begin_query(fd_context(pctx
), q
);
76 fd_end_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
78 struct fd_query
*q
= fd_query(pq
);
80 /* there are a couple special cases, which don't have
81 * a matching ->begin_query():
83 if (skip_begin_query(q
->type
) && !q
->active
)
84 fd_begin_query(pctx
, pq
);
89 q
->funcs
->end_query(fd_context(pctx
), q
);
96 fd_get_query_result(struct pipe_context
*pctx
, struct pipe_query
*pq
,
97 boolean wait
, union pipe_query_result
*result
)
99 struct fd_query
*q
= fd_query(pq
);
104 util_query_clear_result(result
, q
->type
);
106 return q
->funcs
->get_query_result(fd_context(pctx
), q
, wait
, result
);
110 fd_render_condition(struct pipe_context
*pctx
, struct pipe_query
*pq
,
111 boolean condition
, enum pipe_render_cond_flag mode
)
113 struct fd_context
*ctx
= fd_context(pctx
);
114 ctx
->cond_query
= pq
;
115 ctx
->cond_cond
= condition
;
116 ctx
->cond_mode
= mode
;
119 #define _Q(_name, _query_type, _type, _result_type) { \
121 .query_type = _query_type, \
122 .type = PIPE_DRIVER_QUERY_TYPE_ ## _type, \
123 .result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_ ## _result_type, \
124 .group_id = ~(unsigned)0, \
127 #define FQ(_name, _query_type, _type, _result_type) \
128 _Q(_name, FD_QUERY_ ## _query_type, _type, _result_type)
130 #define PQ(_name, _query_type, _type, _result_type) \
131 _Q(_name, PIPE_QUERY_ ## _query_type, _type, _result_type)
133 static const struct pipe_driver_query_info sw_query_list
[] = {
134 FQ("draw-calls", DRAW_CALLS
, UINT64
, AVERAGE
),
135 FQ("batches", BATCH_TOTAL
, UINT64
, AVERAGE
),
136 FQ("batches-sysmem", BATCH_SYSMEM
, UINT64
, AVERAGE
),
137 FQ("batches-gmem", BATCH_GMEM
, UINT64
, AVERAGE
),
138 FQ("batches-nondraw", BATCH_NONDRAW
, UINT64
, AVERAGE
),
139 FQ("restores", BATCH_RESTORE
, UINT64
, AVERAGE
),
140 PQ("prims-emitted", PRIMITIVES_EMITTED
, UINT64
, AVERAGE
),
141 FQ("staging", STAGING_UPLOADS
, UINT64
, AVERAGE
),
142 FQ("shadow", SHADOW_UPLOADS
, UINT64
, AVERAGE
),
143 FQ("vsregs", VS_REGS
, FLOAT
, AVERAGE
),
144 FQ("fsregs", FS_REGS
, FLOAT
, AVERAGE
),
148 fd_get_driver_query_info(struct pipe_screen
*pscreen
,
149 unsigned index
, struct pipe_driver_query_info
*info
)
151 struct fd_screen
*screen
= fd_screen(pscreen
);
154 return ARRAY_SIZE(sw_query_list
) + screen
->num_perfcntr_queries
;
156 if (index
>= ARRAY_SIZE(sw_query_list
)) {
157 index
-= ARRAY_SIZE(sw_query_list
);
158 if (index
>= screen
->num_perfcntr_queries
)
160 *info
= screen
->perfcntr_queries
[index
];
164 *info
= sw_query_list
[index
];
169 fd_get_driver_query_group_info(struct pipe_screen
*pscreen
, unsigned index
,
170 struct pipe_driver_query_group_info
*info
)
172 struct fd_screen
*screen
= fd_screen(pscreen
);
175 return screen
->num_perfcntr_groups
;
177 if (index
>= screen
->num_perfcntr_groups
)
180 const struct fd_perfcntr_group
*g
= &screen
->perfcntr_groups
[index
];
182 info
->name
= g
->name
;
183 info
->max_active_queries
= g
->num_counters
;
184 info
->num_queries
= g
->num_countables
;
190 fd_set_active_query_state(struct pipe_context
*pipe
, boolean enable
)
195 setup_perfcntr_query_info(struct fd_screen
*screen
)
197 unsigned num_queries
= 0;
199 for (unsigned i
= 0; i
< screen
->num_perfcntr_groups
; i
++)
200 num_queries
+= screen
->perfcntr_groups
[i
].num_countables
;
202 screen
->perfcntr_queries
=
203 calloc(num_queries
, sizeof(screen
->perfcntr_queries
[0]));
204 screen
->num_perfcntr_queries
= num_queries
;
207 for (unsigned i
= 0; i
< screen
->num_perfcntr_groups
; i
++) {
208 const struct fd_perfcntr_group
*g
= &screen
->perfcntr_groups
[i
];
209 for (unsigned j
= 0; j
< g
->num_countables
; j
++) {
210 struct pipe_driver_query_info
*info
=
211 &screen
->perfcntr_queries
[idx
];
212 const struct fd_perfcntr_countable
*c
=
215 info
->name
= c
->name
;
216 info
->query_type
= FD_QUERY_FIRST_PERFCNTR
+ idx
;
217 info
->type
= c
->query_type
;
218 info
->result_type
= c
->result_type
;
220 info
->flags
= PIPE_DRIVER_QUERY_FLAG_BATCH
;
228 fd_query_screen_init(struct pipe_screen
*pscreen
)
230 pscreen
->get_driver_query_info
= fd_get_driver_query_info
;
231 pscreen
->get_driver_query_group_info
= fd_get_driver_query_group_info
;
232 setup_perfcntr_query_info(fd_screen(pscreen
));
236 fd_query_context_init(struct pipe_context
*pctx
)
238 pctx
->create_query
= fd_create_query
;
239 pctx
->destroy_query
= fd_destroy_query
;
240 pctx
->begin_query
= fd_begin_query
;
241 pctx
->end_query
= fd_end_query
;
242 pctx
->get_query_result
= fd_get_query_result
;
243 pctx
->set_active_query_state
= fd_set_active_query_state
;
244 pctx
->render_condition
= fd_render_condition
;