2 * Copyright (c) 2017 Etnaviv Project
3 * Copyright (C) 2017 Zodiac Inflight Innovations
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * Rob Clark <robclark@freedesktop.org>
26 * Christian Gmeiner <christian.gmeiner@gmail.com>
29 #include "util/u_memory.h"
31 #include "etnaviv_context.h"
32 #include "etnaviv_debug.h"
33 #include "etnaviv_emit.h"
34 #include "etnaviv_query_acc.h"
38 struct etna_acc_query base
;
40 struct etna_perfmon_signal
*signal
;
44 static inline struct etna_pm_query
*
45 etna_pm_query(struct etna_acc_query
*aq
)
47 return (struct etna_pm_query
*)aq
;
51 pm_add_signal(struct etna_pm_query
*pq
, struct etna_perfmon
*perfmon
,
52 const struct etna_perfmon_config
*cfg
)
54 struct etna_perfmon_signal
*signal
= etna_pm_query_signal(perfmon
, cfg
->source
);
60 pm_query(struct etna_context
*ctx
, struct etna_acc_query
*aq
, unsigned flags
)
62 struct etna_cmd_stream
*stream
= ctx
->stream
;
63 struct etna_pm_query
*pq
= etna_pm_query(aq
);
67 if (aq
->samples
> 127) {
69 BUG("samples overflow perfmon");
72 /* offset 0 is reserved for seq number */
73 offset
= 1 + aq
->samples
;
77 /* skip seq number of 0 as the buffer got zeroed out */
78 pq
->sequence
= MAX2(pq
->sequence
, 1);
80 struct etna_perf p
= {
82 .sequence
= pq
->sequence
,
83 .bo
= etna_resource(aq
->prsc
)->bo
,
88 etna_cmd_stream_perf(stream
, &p
);
89 resource_written(ctx
, aq
->prsc
);
91 /* force a flush in !wait case in etna_acc_get_query_result(..) */
96 perfmon_supports(unsigned query_type
)
98 return !!etna_pm_query_config(query_type
);
101 static struct etna_acc_query
*
102 perfmon_allocate(struct etna_context
*ctx
, unsigned query_type
)
104 struct etna_pm_query
*pq
;
105 const struct etna_perfmon_config
*cfg
;
107 cfg
= etna_pm_query_config(query_type
);
111 if (!etna_pm_cfg_supported(ctx
->screen
->perfmon
, cfg
))
114 pq
= CALLOC_STRUCT(etna_pm_query
);
118 pm_add_signal(pq
, ctx
->screen
->perfmon
, cfg
);
124 perfmon_resume(struct etna_acc_query
*aq
, struct etna_context
*ctx
)
126 pm_query(ctx
, aq
, ETNA_PM_PROCESS_PRE
);
130 perfmon_suspend(struct etna_acc_query
*aq
, struct etna_context
*ctx
)
132 pm_query(ctx
, aq
, ETNA_PM_PROCESS_POST
);
136 perfmon_result(struct etna_acc_query
*aq
, void *buf
,
137 union pipe_query_result
*result
)
139 const struct etna_pm_query
*pq
= etna_pm_query(aq
);
141 uint32_t *ptr
= (uint32_t *)buf
;
143 /* check seq number */
144 if (pq
->sequence
> ptr
[0])
147 /* jump over seq number */
150 assert(aq
->samples
% 2 == 0);
152 /* each pair has a start and end value */
153 for (unsigned i
= 0; i
< aq
->samples
; i
+= 2)
154 sum
+= *(ptr
+ i
+ 1) - *(ptr
+ i
);
161 const struct etna_acc_sample_provider perfmon_provider
= {
162 .supports
= perfmon_supports
,
163 .allocate
= perfmon_allocate
,
164 .resume
= perfmon_resume
,
165 .suspend
= perfmon_suspend
,
166 .result
= perfmon_result
,