Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/freedreno/freedreno_query_sw.c
4570 views
1
/*
2
* Copyright (C) 2014 Rob Clark <[email protected]>
3
*
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:
10
*
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
13
* Software.
14
*
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
21
* SOFTWARE.
22
*
23
* Authors:
24
* Rob Clark <[email protected]>
25
*/
26
27
#include "pipe/p_state.h"
28
#include "util/os_time.h"
29
#include "util/u_inlines.h"
30
#include "util/u_memory.h"
31
#include "util/u_string.h"
32
33
#include "freedreno_context.h"
34
#include "freedreno_query_sw.h"
35
#include "freedreno_util.h"
36
37
/*
38
* SW Queries:
39
*
40
* In the core, we have some support for basic sw counters
41
*/
42
43
static void
44
fd_sw_destroy_query(struct fd_context *ctx, struct fd_query *q)
45
{
46
struct fd_sw_query *sq = fd_sw_query(q);
47
free(sq);
48
}
49
50
static uint64_t
51
read_counter(struct fd_context *ctx, int type) assert_dt
52
{
53
switch (type) {
54
case PIPE_QUERY_PRIMITIVES_GENERATED:
55
return ctx->stats.prims_generated;
56
case PIPE_QUERY_PRIMITIVES_EMITTED:
57
return ctx->stats.prims_emitted;
58
case FD_QUERY_DRAW_CALLS:
59
return ctx->stats.draw_calls;
60
case FD_QUERY_BATCH_TOTAL:
61
return ctx->stats.batch_total;
62
case FD_QUERY_BATCH_SYSMEM:
63
return ctx->stats.batch_sysmem;
64
case FD_QUERY_BATCH_GMEM:
65
return ctx->stats.batch_gmem;
66
case FD_QUERY_BATCH_NONDRAW:
67
return ctx->stats.batch_nondraw;
68
case FD_QUERY_BATCH_RESTORE:
69
return ctx->stats.batch_restore;
70
case FD_QUERY_STAGING_UPLOADS:
71
return ctx->stats.staging_uploads;
72
case FD_QUERY_SHADOW_UPLOADS:
73
return ctx->stats.shadow_uploads;
74
case FD_QUERY_VS_REGS:
75
return ctx->stats.vs_regs;
76
case FD_QUERY_FS_REGS:
77
return ctx->stats.fs_regs;
78
}
79
return 0;
80
}
81
82
static bool
83
is_time_rate_query(struct fd_query *q)
84
{
85
switch (q->type) {
86
case FD_QUERY_BATCH_TOTAL:
87
case FD_QUERY_BATCH_SYSMEM:
88
case FD_QUERY_BATCH_GMEM:
89
case FD_QUERY_BATCH_NONDRAW:
90
case FD_QUERY_BATCH_RESTORE:
91
case FD_QUERY_STAGING_UPLOADS:
92
case FD_QUERY_SHADOW_UPLOADS:
93
return true;
94
default:
95
return false;
96
}
97
}
98
99
static bool
100
is_draw_rate_query(struct fd_query *q)
101
{
102
switch (q->type) {
103
case FD_QUERY_VS_REGS:
104
case FD_QUERY_FS_REGS:
105
return true;
106
default:
107
return false;
108
}
109
}
110
111
static void
112
fd_sw_begin_query(struct fd_context *ctx, struct fd_query *q) assert_dt
113
{
114
struct fd_sw_query *sq = fd_sw_query(q);
115
116
ctx->stats_users++;
117
118
sq->begin_value = read_counter(ctx, q->type);
119
if (is_time_rate_query(q)) {
120
sq->begin_time = os_time_get();
121
} else if (is_draw_rate_query(q)) {
122
sq->begin_time = ctx->stats.draw_calls;
123
}
124
}
125
126
static void
127
fd_sw_end_query(struct fd_context *ctx, struct fd_query *q) assert_dt
128
{
129
struct fd_sw_query *sq = fd_sw_query(q);
130
131
assert(ctx->stats_users > 0);
132
ctx->stats_users--;
133
134
sq->end_value = read_counter(ctx, q->type);
135
if (is_time_rate_query(q)) {
136
sq->end_time = os_time_get();
137
} else if (is_draw_rate_query(q)) {
138
sq->end_time = ctx->stats.draw_calls;
139
}
140
}
141
142
static bool
143
fd_sw_get_query_result(struct fd_context *ctx, struct fd_query *q, bool wait,
144
union pipe_query_result *result)
145
{
146
struct fd_sw_query *sq = fd_sw_query(q);
147
148
result->u64 = sq->end_value - sq->begin_value;
149
150
if (is_time_rate_query(q)) {
151
double fps =
152
(result->u64 * 1000000) / (double)(sq->end_time - sq->begin_time);
153
result->u64 = (uint64_t)fps;
154
} else if (is_draw_rate_query(q)) {
155
double avg =
156
((double)result->u64) / (double)(sq->end_time - sq->begin_time);
157
result->f = avg;
158
}
159
160
return true;
161
}
162
163
static const struct fd_query_funcs sw_query_funcs = {
164
.destroy_query = fd_sw_destroy_query,
165
.begin_query = fd_sw_begin_query,
166
.end_query = fd_sw_end_query,
167
.get_query_result = fd_sw_get_query_result,
168
};
169
170
struct fd_query *
171
fd_sw_create_query(struct fd_context *ctx, unsigned query_type, unsigned index)
172
{
173
struct fd_sw_query *sq;
174
struct fd_query *q;
175
176
switch (query_type) {
177
case PIPE_QUERY_PRIMITIVES_GENERATED:
178
case PIPE_QUERY_PRIMITIVES_EMITTED:
179
case FD_QUERY_DRAW_CALLS:
180
case FD_QUERY_BATCH_TOTAL:
181
case FD_QUERY_BATCH_SYSMEM:
182
case FD_QUERY_BATCH_GMEM:
183
case FD_QUERY_BATCH_NONDRAW:
184
case FD_QUERY_BATCH_RESTORE:
185
case FD_QUERY_STAGING_UPLOADS:
186
case FD_QUERY_SHADOW_UPLOADS:
187
case FD_QUERY_VS_REGS:
188
case FD_QUERY_FS_REGS:
189
break;
190
default:
191
return NULL;
192
}
193
194
sq = CALLOC_STRUCT(fd_sw_query);
195
if (!sq)
196
return NULL;
197
198
q = &sq->base;
199
q->funcs = &sw_query_funcs;
200
q->type = query_type;
201
202
return q;
203
}
204
205