Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/etnaviv/etnaviv_query_acc_perfmon.c
4570 views
1
/*
2
* Copyright (c) 2017 Etnaviv Project
3
* Copyright (C) 2017 Zodiac Inflight Innovations
4
*
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:
11
*
12
* The above copyright notice and this permission notice (including the
13
* next paragraph) shall be included in all copies or substantial portions
14
* of the Software.
15
*
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.
23
*
24
* Authors:
25
* Rob Clark <[email protected]>
26
* Christian Gmeiner <[email protected]>
27
*/
28
29
#include "util/u_memory.h"
30
31
#include "etnaviv_context.h"
32
#include "etnaviv_debug.h"
33
#include "etnaviv_emit.h"
34
#include "etnaviv_query_acc.h"
35
36
struct etna_pm_query
37
{
38
struct etna_acc_query base;
39
40
struct etna_perfmon_signal *signal;
41
unsigned sequence;
42
};
43
44
static inline struct etna_pm_query *
45
etna_pm_query(struct etna_acc_query *aq)
46
{
47
return (struct etna_pm_query *)aq;
48
}
49
50
static inline void
51
pm_add_signal(struct etna_pm_query *pq, struct etna_perfmon *perfmon,
52
const struct etna_perfmon_config *cfg)
53
{
54
struct etna_perfmon_signal *signal = etna_pm_query_signal(perfmon, cfg->source);
55
56
pq->signal = signal;
57
}
58
59
static void
60
pm_query(struct etna_context *ctx, struct etna_acc_query *aq, unsigned flags)
61
{
62
struct etna_cmd_stream *stream = ctx->stream;
63
struct etna_pm_query *pq = etna_pm_query(aq);
64
unsigned offset;
65
assert(flags);
66
67
if (aq->samples > 127) {
68
aq->samples = 127;
69
BUG("samples overflow perfmon");
70
}
71
72
/* offset 0 is reserved for seq number */
73
offset = 1 + aq->samples;
74
75
pq->sequence++;
76
77
/* skip seq number of 0 as the buffer got zeroed out */
78
pq->sequence = MAX2(pq->sequence, 1);
79
80
struct etna_perf p = {
81
.flags = flags,
82
.sequence = pq->sequence,
83
.bo = etna_resource(aq->prsc)->bo,
84
.signal = pq->signal,
85
.offset = offset
86
};
87
88
etna_cmd_stream_perf(stream, &p);
89
resource_written(ctx, aq->prsc);
90
91
/* force a flush in !wait case in etna_acc_get_query_result(..) */
92
aq->no_wait_cnt = 10;
93
}
94
95
static bool
96
perfmon_supports(unsigned query_type)
97
{
98
return !!etna_pm_query_config(query_type);
99
}
100
101
static struct etna_acc_query *
102
perfmon_allocate(struct etna_context *ctx, unsigned query_type)
103
{
104
struct etna_pm_query *pq;
105
const struct etna_perfmon_config *cfg;
106
107
cfg = etna_pm_query_config(query_type);
108
if (!cfg)
109
return false;
110
111
if (!etna_pm_cfg_supported(ctx->screen->perfmon, cfg))
112
return false;
113
114
pq = CALLOC_STRUCT(etna_pm_query);
115
if (!pq)
116
return NULL;
117
118
pm_add_signal(pq, ctx->screen->perfmon, cfg);
119
120
return &pq->base;
121
}
122
123
static void
124
perfmon_resume(struct etna_acc_query *aq, struct etna_context *ctx)
125
{
126
pm_query(ctx, aq, ETNA_PM_PROCESS_PRE);
127
}
128
129
static void
130
perfmon_suspend(struct etna_acc_query *aq, struct etna_context *ctx)
131
{
132
pm_query(ctx, aq, ETNA_PM_PROCESS_POST);
133
}
134
135
static bool
136
perfmon_result(struct etna_acc_query *aq, void *buf,
137
union pipe_query_result *result)
138
{
139
const struct etna_pm_query *pq = etna_pm_query(aq);
140
uint32_t sum = 0;
141
uint32_t *ptr = (uint32_t *)buf;
142
143
/* check seq number */
144
if (pq->sequence > ptr[0])
145
return false;
146
147
/* jump over seq number */
148
ptr++;
149
150
assert(aq->samples % 2 == 0);
151
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);
155
156
result->u32 = sum;
157
158
return true;
159
}
160
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,
167
};
168
169