Path: blob/21.2-virgl/src/gallium/frontends/xvmc/tests/xvmc_bench.c
4573 views
/**************************************************************************1*2* Copyright 2009 Younes Manton.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627/* Force assertions, even on release builds. */28#undef NDEBUG29#include <assert.h>30#include <stdio.h>31#include <string.h>32#include <stdlib.h>33#include <sys/time.h>34#include "testlib.h"3536#define MACROBLOCK_WIDTH 1637#define MACROBLOCK_HEIGHT 1638#define BLOCKS_PER_MACROBLOCK 63940#define DEFAULT_INPUT_WIDTH 72041#define DEFAULT_INPUT_HEIGHT 48042#define DEFAULT_REPS 1004344#define PIPELINE_STEP_MC 145#define PIPELINE_STEP_CSC 246#define PIPELINE_STEP_SWAP 44748#define MB_TYPE_I 149#define MB_TYPE_P 250#define MB_TYPE_B 45152struct Config53{54unsigned int input_width;55unsigned int input_height;56unsigned int output_width;57unsigned int output_height;58unsigned int pipeline;59unsigned int mb_types;60unsigned int reps;61};6263void ParseArgs(int argc, char **argv, struct Config *config);6465void ParseArgs(int argc, char **argv, struct Config *config)66{67int fail = 0;68int i;6970config->input_width = DEFAULT_INPUT_WIDTH;71config->input_height = DEFAULT_INPUT_HEIGHT;72config->output_width = 0;73config->output_height = 0;74config->pipeline = 0;75config->mb_types = 0;76config->reps = DEFAULT_REPS;7778for (i = 1; i < argc && !fail; ++i)79{80if (!strcmp(argv[i], "-iw"))81{82if (sscanf(argv[++i], "%u", &config->input_width) != 1)83fail = 1;84}85else if (!strcmp(argv[i], "-ih"))86{87if (sscanf(argv[++i], "%u", &config->input_height) != 1)88fail = 1;89}90else if (!strcmp(argv[i], "-ow"))91{92if (sscanf(argv[++i], "%u", &config->output_width) != 1)93fail = 1;94}95else if (!strcmp(argv[i], "-oh"))96{97if (sscanf(argv[++i], "%u", &config->output_height) != 1)98fail = 1;99}100else if (!strcmp(argv[i], "-p"))101{102char *token = strtok(argv[++i], ",");103104while (token && !fail)105{106if (!strcmp(token, "mc"))107config->pipeline |= PIPELINE_STEP_MC;108else if (!strcmp(token, "csc"))109config->pipeline |= PIPELINE_STEP_CSC;110else if (!strcmp(token, "swp"))111config->pipeline |= PIPELINE_STEP_SWAP;112else113fail = 1;114115if (!fail)116token = strtok(NULL, ",");117}118}119else if (!strcmp(argv[i], "-mb"))120{121char *token = strtok(argv[++i], ",");122123while (token && !fail)124{125if (strcmp(token, "i") == 0)126config->mb_types |= MB_TYPE_I;127else if (strcmp(token, "p") == 0)128config->mb_types |= MB_TYPE_P;129else if (strcmp(token, "b") == 0)130config->mb_types |= MB_TYPE_B;131else132fail = 1;133134if (!fail)135token = strtok(NULL, ",");136}137}138else if (!strcmp(argv[i], "-r"))139{140if (sscanf(argv[++i], "%u", &config->reps) != 1)141fail = 1;142}143else144fail = 1;145}146147if (fail)148{149fprintf(150stderr,151"Bad argument.\n"152"\n"153"Usage: %s [options]\n"154"\t-iw <width>\tInput width\n"155"\t-ih <height>\tInput height\n"156"\t-ow <width>\tOutput width\n"157"\t-oh <height>\tOutput height\n"158"\t-p <pipeline>\tPipeline to test\n"159"\t-mb <mb type>\tMacroBlock types to use\n"160"\t-r <reps>\tRepetitions\n\n"161"\tPipeline steps: mc,csc,swap\n"162"\tMB types: i,p,b\n",163argv[0]164);165exit(1);166}167168if (config->output_width == 0)169config->output_width = config->input_width;170if (config->output_height == 0)171config->output_height = config->input_height;172if (!config->pipeline)173config->pipeline = PIPELINE_STEP_MC | PIPELINE_STEP_CSC | PIPELINE_STEP_SWAP;174if (!config->mb_types)175config->mb_types = MB_TYPE_I | MB_TYPE_P | MB_TYPE_B;176}177178int main(int argc, char **argv)179{180struct Config config;181Display *display;182Window root, window;183const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};184XvPortID port_num;185int surface_type_id;186unsigned int is_overlay, intra_unsigned;187int colorkey;188XvMCContext context;189XvMCSurface surface;190XvMCBlockArray block_array;191XvMCMacroBlockArray mb_array;192unsigned int mbw, mbh;193unsigned int mbx, mby;194unsigned int reps;195struct timeval start, stop, diff;196double diff_secs;197198ParseArgs(argc, argv, &config);199200mbw = align(config.input_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;201mbh = align(config.input_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT;202203display = XOpenDisplay(NULL);204205if (!GetPort206(207display,208config.input_width,209config.input_height,210XVMC_CHROMA_FORMAT_420,211mc_types,2122,213&port_num,214&surface_type_id,215&is_overlay,216&intra_unsigned217))218{219XCloseDisplay(display);220fprintf(stderr, "Error, unable to find a good port.\n");221exit(1);222}223224if (is_overlay)225{226Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);227XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);228}229else230{231colorkey = 0;232}233234root = XDefaultRootWindow(display);235window = XCreateSimpleWindow(display, root, 0, 0, config.output_width, config.output_height, 0, 0, colorkey);236237assert(XvMCCreateContext(display, port_num, surface_type_id, config.input_width, config.input_height, XVMC_DIRECT, &context) == Success);238assert(XvMCCreateSurface(display, &context, &surface) == Success);239assert(XvMCCreateBlocks(display, &context, mbw * mbh * BLOCKS_PER_MACROBLOCK, &block_array) == Success);240assert(XvMCCreateMacroBlocks(display, &context, mbw * mbh, &mb_array) == Success);241242for (mby = 0; mby < mbh; ++mby)243for (mbx = 0; mbx < mbw; ++mbx)244{245mb_array.macro_blocks[mby * mbw + mbx].x = mbx;246mb_array.macro_blocks[mby * mbw + mbx].y = mby;247mb_array.macro_blocks[mby * mbw + mbx].macroblock_type = XVMC_MB_TYPE_INTRA;248/*mb->motion_type = ;*/249/*mb->motion_vertical_field_select = ;*/250mb_array.macro_blocks[mby * mbw + mbx].dct_type = XVMC_DCT_TYPE_FRAME;251/*mb->PMV[0][0][0] = ;252mb->PMV[0][0][1] = ;253mb->PMV[0][1][0] = ;254mb->PMV[0][1][1] = ;255mb->PMV[1][0][0] = ;256mb->PMV[1][0][1] = ;257mb->PMV[1][1][0] = ;258mb->PMV[1][1][1] = ;*/259mb_array.macro_blocks[mby * mbw + mbx].index = (mby * mbw + mbx) * BLOCKS_PER_MACROBLOCK;260mb_array.macro_blocks[mby * mbw + mbx].coded_block_pattern = 0x3F;261}262263XSelectInput(display, window, ExposureMask | KeyPressMask);264XMapWindow(display, window);265XSync(display, 0);266267gettimeofday(&start, NULL);268269for (reps = 0; reps < config.reps; ++reps)270{271if (config.pipeline & PIPELINE_STEP_MC)272{273assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, mbw * mbh, 0, &mb_array, &block_array) == Success);274assert(XvMCFlushSurface(display, &surface) == Success);275}276if (config.pipeline & PIPELINE_STEP_CSC)277assert(XvMCPutSurface(display, &surface, window, 0, 0, config.input_width, config.input_height, 0, 0, config.output_width, config.output_height, XVMC_FRAME_PICTURE) == Success);278}279280gettimeofday(&stop, NULL);281282timeval_subtract(&diff, &stop, &start);283diff_secs = (double)diff.tv_sec + (double)diff.tv_usec / 1000000.0;284285printf("XvMC Benchmark\n");286printf("Input: %u,%u\nOutput: %u,%u\n", config.input_width, config.input_height, config.output_width, config.output_height);287printf("Pipeline: ");288if (config.pipeline & PIPELINE_STEP_MC)289printf("|mc|");290if (config.pipeline & PIPELINE_STEP_CSC)291printf("|csc|");292if (config.pipeline & PIPELINE_STEP_SWAP)293printf("|swap|");294printf("\n");295printf("Reps: %u\n", config.reps);296printf("Total time: %.2lf (%.2lf reps / sec)\n", diff_secs, config.reps / diff_secs);297298assert(XvMCDestroyBlocks(display, &block_array) == Success);299assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success);300assert(XvMCDestroySurface(display, &surface) == Success);301assert(XvMCDestroyContext(display, &context) == Success);302303XvUngrabPort(display, port_num, CurrentTime);304XDestroyWindow(display, window);305XCloseDisplay(display);306307return 0;308}309310311