Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/xvmc/tests/xvmc_bench.c
4573 views
1
/**************************************************************************
2
*
3
* Copyright 2009 Younes Manton.
4
* All Rights Reserved.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
16
* of the Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*
26
**************************************************************************/
27
28
/* Force assertions, even on release builds. */
29
#undef NDEBUG
30
#include <assert.h>
31
#include <stdio.h>
32
#include <string.h>
33
#include <stdlib.h>
34
#include <sys/time.h>
35
#include "testlib.h"
36
37
#define MACROBLOCK_WIDTH 16
38
#define MACROBLOCK_HEIGHT 16
39
#define BLOCKS_PER_MACROBLOCK 6
40
41
#define DEFAULT_INPUT_WIDTH 720
42
#define DEFAULT_INPUT_HEIGHT 480
43
#define DEFAULT_REPS 100
44
45
#define PIPELINE_STEP_MC 1
46
#define PIPELINE_STEP_CSC 2
47
#define PIPELINE_STEP_SWAP 4
48
49
#define MB_TYPE_I 1
50
#define MB_TYPE_P 2
51
#define MB_TYPE_B 4
52
53
struct Config
54
{
55
unsigned int input_width;
56
unsigned int input_height;
57
unsigned int output_width;
58
unsigned int output_height;
59
unsigned int pipeline;
60
unsigned int mb_types;
61
unsigned int reps;
62
};
63
64
void ParseArgs(int argc, char **argv, struct Config *config);
65
66
void ParseArgs(int argc, char **argv, struct Config *config)
67
{
68
int fail = 0;
69
int i;
70
71
config->input_width = DEFAULT_INPUT_WIDTH;
72
config->input_height = DEFAULT_INPUT_HEIGHT;
73
config->output_width = 0;
74
config->output_height = 0;
75
config->pipeline = 0;
76
config->mb_types = 0;
77
config->reps = DEFAULT_REPS;
78
79
for (i = 1; i < argc && !fail; ++i)
80
{
81
if (!strcmp(argv[i], "-iw"))
82
{
83
if (sscanf(argv[++i], "%u", &config->input_width) != 1)
84
fail = 1;
85
}
86
else if (!strcmp(argv[i], "-ih"))
87
{
88
if (sscanf(argv[++i], "%u", &config->input_height) != 1)
89
fail = 1;
90
}
91
else if (!strcmp(argv[i], "-ow"))
92
{
93
if (sscanf(argv[++i], "%u", &config->output_width) != 1)
94
fail = 1;
95
}
96
else if (!strcmp(argv[i], "-oh"))
97
{
98
if (sscanf(argv[++i], "%u", &config->output_height) != 1)
99
fail = 1;
100
}
101
else if (!strcmp(argv[i], "-p"))
102
{
103
char *token = strtok(argv[++i], ",");
104
105
while (token && !fail)
106
{
107
if (!strcmp(token, "mc"))
108
config->pipeline |= PIPELINE_STEP_MC;
109
else if (!strcmp(token, "csc"))
110
config->pipeline |= PIPELINE_STEP_CSC;
111
else if (!strcmp(token, "swp"))
112
config->pipeline |= PIPELINE_STEP_SWAP;
113
else
114
fail = 1;
115
116
if (!fail)
117
token = strtok(NULL, ",");
118
}
119
}
120
else if (!strcmp(argv[i], "-mb"))
121
{
122
char *token = strtok(argv[++i], ",");
123
124
while (token && !fail)
125
{
126
if (strcmp(token, "i") == 0)
127
config->mb_types |= MB_TYPE_I;
128
else if (strcmp(token, "p") == 0)
129
config->mb_types |= MB_TYPE_P;
130
else if (strcmp(token, "b") == 0)
131
config->mb_types |= MB_TYPE_B;
132
else
133
fail = 1;
134
135
if (!fail)
136
token = strtok(NULL, ",");
137
}
138
}
139
else if (!strcmp(argv[i], "-r"))
140
{
141
if (sscanf(argv[++i], "%u", &config->reps) != 1)
142
fail = 1;
143
}
144
else
145
fail = 1;
146
}
147
148
if (fail)
149
{
150
fprintf(
151
stderr,
152
"Bad argument.\n"
153
"\n"
154
"Usage: %s [options]\n"
155
"\t-iw <width>\tInput width\n"
156
"\t-ih <height>\tInput height\n"
157
"\t-ow <width>\tOutput width\n"
158
"\t-oh <height>\tOutput height\n"
159
"\t-p <pipeline>\tPipeline to test\n"
160
"\t-mb <mb type>\tMacroBlock types to use\n"
161
"\t-r <reps>\tRepetitions\n\n"
162
"\tPipeline steps: mc,csc,swap\n"
163
"\tMB types: i,p,b\n",
164
argv[0]
165
);
166
exit(1);
167
}
168
169
if (config->output_width == 0)
170
config->output_width = config->input_width;
171
if (config->output_height == 0)
172
config->output_height = config->input_height;
173
if (!config->pipeline)
174
config->pipeline = PIPELINE_STEP_MC | PIPELINE_STEP_CSC | PIPELINE_STEP_SWAP;
175
if (!config->mb_types)
176
config->mb_types = MB_TYPE_I | MB_TYPE_P | MB_TYPE_B;
177
}
178
179
int main(int argc, char **argv)
180
{
181
struct Config config;
182
Display *display;
183
Window root, window;
184
const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
185
XvPortID port_num;
186
int surface_type_id;
187
unsigned int is_overlay, intra_unsigned;
188
int colorkey;
189
XvMCContext context;
190
XvMCSurface surface;
191
XvMCBlockArray block_array;
192
XvMCMacroBlockArray mb_array;
193
unsigned int mbw, mbh;
194
unsigned int mbx, mby;
195
unsigned int reps;
196
struct timeval start, stop, diff;
197
double diff_secs;
198
199
ParseArgs(argc, argv, &config);
200
201
mbw = align(config.input_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
202
mbh = align(config.input_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT;
203
204
display = XOpenDisplay(NULL);
205
206
if (!GetPort
207
(
208
display,
209
config.input_width,
210
config.input_height,
211
XVMC_CHROMA_FORMAT_420,
212
mc_types,
213
2,
214
&port_num,
215
&surface_type_id,
216
&is_overlay,
217
&intra_unsigned
218
))
219
{
220
XCloseDisplay(display);
221
fprintf(stderr, "Error, unable to find a good port.\n");
222
exit(1);
223
}
224
225
if (is_overlay)
226
{
227
Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
228
XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
229
}
230
else
231
{
232
colorkey = 0;
233
}
234
235
root = XDefaultRootWindow(display);
236
window = XCreateSimpleWindow(display, root, 0, 0, config.output_width, config.output_height, 0, 0, colorkey);
237
238
assert(XvMCCreateContext(display, port_num, surface_type_id, config.input_width, config.input_height, XVMC_DIRECT, &context) == Success);
239
assert(XvMCCreateSurface(display, &context, &surface) == Success);
240
assert(XvMCCreateBlocks(display, &context, mbw * mbh * BLOCKS_PER_MACROBLOCK, &block_array) == Success);
241
assert(XvMCCreateMacroBlocks(display, &context, mbw * mbh, &mb_array) == Success);
242
243
for (mby = 0; mby < mbh; ++mby)
244
for (mbx = 0; mbx < mbw; ++mbx)
245
{
246
mb_array.macro_blocks[mby * mbw + mbx].x = mbx;
247
mb_array.macro_blocks[mby * mbw + mbx].y = mby;
248
mb_array.macro_blocks[mby * mbw + mbx].macroblock_type = XVMC_MB_TYPE_INTRA;
249
/*mb->motion_type = ;*/
250
/*mb->motion_vertical_field_select = ;*/
251
mb_array.macro_blocks[mby * mbw + mbx].dct_type = XVMC_DCT_TYPE_FRAME;
252
/*mb->PMV[0][0][0] = ;
253
mb->PMV[0][0][1] = ;
254
mb->PMV[0][1][0] = ;
255
mb->PMV[0][1][1] = ;
256
mb->PMV[1][0][0] = ;
257
mb->PMV[1][0][1] = ;
258
mb->PMV[1][1][0] = ;
259
mb->PMV[1][1][1] = ;*/
260
mb_array.macro_blocks[mby * mbw + mbx].index = (mby * mbw + mbx) * BLOCKS_PER_MACROBLOCK;
261
mb_array.macro_blocks[mby * mbw + mbx].coded_block_pattern = 0x3F;
262
}
263
264
XSelectInput(display, window, ExposureMask | KeyPressMask);
265
XMapWindow(display, window);
266
XSync(display, 0);
267
268
gettimeofday(&start, NULL);
269
270
for (reps = 0; reps < config.reps; ++reps)
271
{
272
if (config.pipeline & PIPELINE_STEP_MC)
273
{
274
assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, mbw * mbh, 0, &mb_array, &block_array) == Success);
275
assert(XvMCFlushSurface(display, &surface) == Success);
276
}
277
if (config.pipeline & PIPELINE_STEP_CSC)
278
assert(XvMCPutSurface(display, &surface, window, 0, 0, config.input_width, config.input_height, 0, 0, config.output_width, config.output_height, XVMC_FRAME_PICTURE) == Success);
279
}
280
281
gettimeofday(&stop, NULL);
282
283
timeval_subtract(&diff, &stop, &start);
284
diff_secs = (double)diff.tv_sec + (double)diff.tv_usec / 1000000.0;
285
286
printf("XvMC Benchmark\n");
287
printf("Input: %u,%u\nOutput: %u,%u\n", config.input_width, config.input_height, config.output_width, config.output_height);
288
printf("Pipeline: ");
289
if (config.pipeline & PIPELINE_STEP_MC)
290
printf("|mc|");
291
if (config.pipeline & PIPELINE_STEP_CSC)
292
printf("|csc|");
293
if (config.pipeline & PIPELINE_STEP_SWAP)
294
printf("|swap|");
295
printf("\n");
296
printf("Reps: %u\n", config.reps);
297
printf("Total time: %.2lf (%.2lf reps / sec)\n", diff_secs, config.reps / diff_secs);
298
299
assert(XvMCDestroyBlocks(display, &block_array) == Success);
300
assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success);
301
assert(XvMCDestroySurface(display, &surface) == Success);
302
assert(XvMCDestroyContext(display, &context) == Success);
303
304
XvUngrabPort(display, port_num, CurrentTime);
305
XDestroyWindow(display, window);
306
XCloseDisplay(display);
307
308
return 0;
309
}
310
311