1 /* -*- mode: C; c-file-style: "k&r"; ttxab-width 4; indent-tabs-mode: t; -*- */
4 * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * Rob Clark <robclark@freedesktop.org>
29 #include "pipe/p_state.h"
30 #include "util/u_memory.h"
32 #include "freedreno_query.h"
33 #include "freedreno_query_sw.h"
34 #include "freedreno_query_hw.h"
35 #include "freedreno_context.h"
36 #include "freedreno_util.h"
39 * Pipe Query interface:
42 static struct pipe_query
*
43 fd_create_query(struct pipe_context
*pctx
, unsigned query_type
, unsigned index
)
45 struct fd_context
*ctx
= fd_context(pctx
);
48 q
= fd_sw_create_query(ctx
, query_type
);
49 if (!q
&& ctx
->create_query
)
50 q
= ctx
->create_query(ctx
, query_type
);
52 return (struct pipe_query
*) q
;
56 fd_destroy_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
58 struct fd_query
*q
= fd_query(pq
);
59 q
->funcs
->destroy_query(fd_context(pctx
), q
);
63 fd_begin_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
65 struct fd_query
*q
= fd_query(pq
);
71 ret
= q
->funcs
->begin_query(fd_context(pctx
), q
);
78 fd_end_query(struct pipe_context
*pctx
, struct pipe_query
*pq
)
80 struct fd_query
*q
= fd_query(pq
);
82 /* there are a couple special cases, which don't have
83 * a matching ->begin_query():
85 if (skip_begin_query(q
->type
) && !q
->active
)
86 fd_begin_query(pctx
, pq
);
91 q
->funcs
->end_query(fd_context(pctx
), q
);
98 fd_get_query_result(struct pipe_context
*pctx
, struct pipe_query
*pq
,
99 boolean wait
, union pipe_query_result
*result
)
101 struct fd_query
*q
= fd_query(pq
);
106 util_query_clear_result(result
, q
->type
);
108 return q
->funcs
->get_query_result(fd_context(pctx
), q
, wait
, result
);
112 fd_render_condition(struct pipe_context
*pctx
, struct pipe_query
*pq
,
113 boolean condition
, enum pipe_render_cond_flag mode
)
115 struct fd_context
*ctx
= fd_context(pctx
);
116 ctx
->cond_query
= pq
;
117 ctx
->cond_cond
= condition
;
118 ctx
->cond_mode
= mode
;
121 #define _Q(_name, _query_type, _type, _result_type) { \
123 .query_type = _query_type, \
124 .type = PIPE_DRIVER_QUERY_TYPE_ ## _type, \
125 .result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_ ## _result_type, \
126 .group_id = ~(unsigned)0, \
129 #define FQ(_name, _query_type, _type, _result_type) \
130 _Q(_name, FD_QUERY_ ## _query_type, _type, _result_type)
132 #define PQ(_name, _query_type, _type, _result_type) \
133 _Q(_name, PIPE_QUERY_ ## _query_type, _type, _result_type)
135 static const struct pipe_driver_query_info sw_query_list
[] = {
136 FQ("draw-calls", DRAW_CALLS
, UINT64
, AVERAGE
),
137 FQ("batches", BATCH_TOTAL
, UINT64
, AVERAGE
),
138 FQ("batches-sysmem", BATCH_SYSMEM
, UINT64
, AVERAGE
),
139 FQ("batches-gmem", BATCH_GMEM
, UINT64
, AVERAGE
),
140 FQ("batches-nondraw", BATCH_NONDRAW
, UINT64
, AVERAGE
),
141 FQ("restores", BATCH_RESTORE
, UINT64
, AVERAGE
),
142 PQ("prims-emitted", PRIMITIVES_EMITTED
, UINT64
, AVERAGE
),
143 FQ("staging", STAGING_UPLOADS
, UINT64
, AVERAGE
),
144 FQ("shadow", SHADOW_UPLOADS
, UINT64
, AVERAGE
),
145 FQ("vsregs", VS_REGS
, FLOAT
, AVERAGE
),
146 FQ("fsregs", FS_REGS
, FLOAT
, AVERAGE
),
150 fd_get_driver_query_info(struct pipe_screen
*pscreen
,
151 unsigned index
, struct pipe_driver_query_info
*info
)
153 struct fd_screen
*screen
= fd_screen(pscreen
);
156 return ARRAY_SIZE(sw_query_list
) + screen
->num_perfcntr_queries
;
158 if (index
>= ARRAY_SIZE(sw_query_list
)) {
159 index
-= ARRAY_SIZE(sw_query_list
);
160 if (index
>= screen
->num_perfcntr_queries
)
162 *info
= screen
->perfcntr_queries
[index
];
166 *info
= sw_query_list
[index
];
171 fd_get_driver_query_group_info(struct pipe_screen
*pscreen
, unsigned index
,
172 struct pipe_driver_query_group_info
*info
)
174 struct fd_screen
*screen
= fd_screen(pscreen
);
177 return screen
->num_perfcntr_groups
;
179 if (index
>= screen
->num_perfcntr_groups
)
182 const struct fd_perfcntr_group
*g
= &screen
->perfcntr_groups
[index
];
184 info
->name
= g
->name
;
185 info
->max_active_queries
= g
->num_counters
;
186 info
->num_queries
= g
->num_countables
;
192 fd_set_active_query_state(struct pipe_context
*pipe
, boolean enable
)
197 setup_perfcntr_query_info(struct fd_screen
*screen
)
199 unsigned num_queries
= 0;
201 for (unsigned i
= 0; i
< screen
->num_perfcntr_groups
; i
++)
202 num_queries
+= screen
->perfcntr_groups
[i
].num_countables
;
204 screen
->perfcntr_queries
=
205 calloc(num_queries
, sizeof(screen
->perfcntr_queries
[0]));
206 screen
->num_perfcntr_queries
= num_queries
;
209 for (unsigned i
= 0; i
< screen
->num_perfcntr_groups
; i
++) {
210 const struct fd_perfcntr_group
*g
= &screen
->perfcntr_groups
[i
];
211 for (unsigned j
= 0; j
< g
->num_countables
; j
++) {
212 struct pipe_driver_query_info
*info
=
213 &screen
->perfcntr_queries
[idx
];
214 const struct fd_perfcntr_countable
*c
=
217 info
->name
= c
->name
;
218 info
->query_type
= FD_QUERY_FIRST_PERFCNTR
+ idx
;
219 info
->type
= c
->query_type
;
220 info
->result_type
= c
->result_type
;
222 info
->flags
= PIPE_DRIVER_QUERY_FLAG_BATCH
;
230 fd_query_screen_init(struct pipe_screen
*pscreen
)
232 pscreen
->get_driver_query_info
= fd_get_driver_query_info
;
233 pscreen
->get_driver_query_group_info
= fd_get_driver_query_group_info
;
234 setup_perfcntr_query_info(fd_screen(pscreen
));
238 fd_query_context_init(struct pipe_context
*pctx
)
240 pctx
->create_query
= fd_create_query
;
241 pctx
->destroy_query
= fd_destroy_query
;
242 pctx
->begin_query
= fd_begin_query
;
243 pctx
->end_query
= fd_end_query
;
244 pctx
->get_query_result
= fd_get_query_result
;
245 pctx
->set_active_query_state
= fd_set_active_query_state
;
246 pctx
->render_condition
= fd_render_condition
;