Path: blob/21.2-virgl/src/gallium/frontends/xvmc/tests/test_rendering.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 "testlib.h"3435#define BLOCK_WIDTH 836#define BLOCK_HEIGHT 837#define BLOCK_SIZE (BLOCK_WIDTH * BLOCK_HEIGHT)38#define MACROBLOCK_WIDTH 1639#define MACROBLOCK_HEIGHT 1640#define MACROBLOCK_WIDTH_IN_BLOCKS (MACROBLOCK_WIDTH / BLOCK_WIDTH)41#define MACROBLOCK_HEIGHT_IN_BLOCKS (MACROBLOCK_HEIGHT / BLOCK_HEIGHT)42#define BLOCKS_PER_MACROBLOCK 64344#define INPUT_WIDTH 6445#define INPUT_HEIGHT 6446#define INPUT_WIDTH_IN_MACROBLOCKS (INPUT_WIDTH / MACROBLOCK_WIDTH)47#define INPUT_HEIGHT_IN_MACROBLOCKS (INPUT_HEIGHT / MACROBLOCK_HEIGHT)48#define NUM_MACROBLOCKS (INPUT_WIDTH_IN_MACROBLOCKS * INPUT_HEIGHT_IN_MACROBLOCKS)4950#define DEFAULT_OUTPUT_WIDTH INPUT_WIDTH51#define DEFAULT_OUTPUT_HEIGHT INPUT_HEIGHT52#define DEFAULT_ACCEPTABLE_ERR 0.015354static void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt)55{56int fail = 0;57int i;5859*output_width = DEFAULT_OUTPUT_WIDTH;60*output_height = DEFAULT_OUTPUT_HEIGHT;61*acceptable_error = DEFAULT_ACCEPTABLE_ERR;62*prompt = 0;6364for (i = 1; i < argc && !fail; ++i)65{66if (!strcmp(argv[i], "-w"))67{68if (sscanf(argv[++i], "%u", output_width) != 1)69fail = 1;70}71else if (!strcmp(argv[i], "-h"))72{73if (sscanf(argv[++i], "%u", output_height) != 1)74fail = 1;75}76else if (!strcmp(argv[i], "-e"))77{78if (sscanf(argv[++i], "%lf", acceptable_error) != 1)79fail = 1;80}81else if (!strcmp(argv[i], "-p"))82*prompt = 1;83else84fail = 1;85}8687if (fail)88{89fprintf(90stderr,91"Bad argument.\n"92"\n"93"Usage: %s [options]\n"94"\t-w <width>\tOutput width\n"95"\t-h <height>\tOutput height\n"96"\t-e <error>\tAcceptable margin of error per pixel, from 0 to 1\n"97"\t-p\tPrompt for quit\n",98argv[0]99);100exit(1);101}102}103104static void Gradient(short *block, unsigned int start, unsigned int stop, int horizontal, unsigned int intra_unsigned)105{106unsigned int x, y;107unsigned int range = stop - start;108109if (horizontal)110{111for (y = 0; y < BLOCK_HEIGHT; ++y)112for (x = 0; x < BLOCK_WIDTH; ++x) {113*block = (short)(start + range * (x / (float)(BLOCK_WIDTH - 1)));114if (intra_unsigned)115*block += 1 << 10;116block++;117}118}119else120{121for (y = 0; y < BLOCK_HEIGHT; ++y)122for (x = 0; x < BLOCK_WIDTH; ++x) {123*block = (short)(start + range * (y / (float)(BLOCK_WIDTH - 1)));124if (intra_unsigned)125*block += 1 << 10;126block++;127}128}129}130131int main(int argc, char **argv)132{133unsigned int output_width;134unsigned int output_height;135double acceptable_error;136int prompt;137Display *display;138Window root, window;139const unsigned int mc_types[] = {XVMC_MOCOMP | XVMC_MPEG_2};140XvPortID port_num;141int surface_type_id;142unsigned int is_overlay, intra_unsigned;143int colorkey;144XvMCContext context;145XvMCSurface surface;146XvMCBlockArray block_array;147XvMCMacroBlockArray mb_array;148int mbx, mby, bx, by;149XvMCMacroBlock *mb;150short *blocks;151int quit = 0;152153ParseArgs(argc, argv, &output_width, &output_height, &acceptable_error, &prompt);154155display = XOpenDisplay(NULL);156157if (!GetPort158(159display,160INPUT_WIDTH,161INPUT_HEIGHT,162XVMC_CHROMA_FORMAT_420,163mc_types,164sizeof(mc_types)/sizeof(*mc_types),165&port_num,166&surface_type_id,167&is_overlay,168&intra_unsigned169))170{171XCloseDisplay(display);172fprintf(stderr, "Error, unable to find a good port.\n");173exit(1);174}175176if (is_overlay)177{178Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);179XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);180}181182root = XDefaultRootWindow(display);183window = XCreateSimpleWindow(display, root, 0, 0, output_width, output_height, 0, 0, colorkey);184185assert(XvMCCreateContext(display, port_num, surface_type_id, INPUT_WIDTH, INPUT_HEIGHT, XVMC_DIRECT, &context) == Success);186assert(XvMCCreateSurface(display, &context, &surface) == Success);187assert(XvMCCreateBlocks(display, &context, NUM_MACROBLOCKS * BLOCKS_PER_MACROBLOCK, &block_array) == Success);188assert(XvMCCreateMacroBlocks(display, &context, NUM_MACROBLOCKS, &mb_array) == Success);189190mb = mb_array.macro_blocks;191blocks = block_array.blocks;192193for (mby = 0; mby < INPUT_HEIGHT_IN_MACROBLOCKS; ++mby)194for (mbx = 0; mbx < INPUT_WIDTH_IN_MACROBLOCKS; ++mbx)195{196mb->x = mbx;197mb->y = mby;198mb->macroblock_type = XVMC_MB_TYPE_INTRA;199/*mb->motion_type = ;*/200/*mb->motion_vertical_field_select = ;*/201mb->dct_type = XVMC_DCT_TYPE_FRAME;202/*mb->PMV[0][0][0] = ;203mb->PMV[0][0][1] = ;204mb->PMV[0][1][0] = ;205mb->PMV[0][1][1] = ;206mb->PMV[1][0][0] = ;207mb->PMV[1][0][1] = ;208mb->PMV[1][1][0] = ;209mb->PMV[1][1][1] = ;*/210mb->index = (mby * INPUT_WIDTH_IN_MACROBLOCKS + mbx) * BLOCKS_PER_MACROBLOCK;211mb->coded_block_pattern = 0x3F;212213mb++;214215for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS; ++by)216for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS; ++bx)217{218const int start = 16, stop = 235, range = stop - start;219220Gradient221(222blocks,223(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),224(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),2251,226intra_unsigned227);228229blocks += BLOCK_SIZE;230}231232for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS / 2; ++by)233for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS / 2; ++bx)234{235const int start = 16, stop = 240, range = stop - start;236237Gradient238(239blocks,240(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),241(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),2421,243intra_unsigned244);245246blocks += BLOCK_SIZE;247248Gradient249(250blocks,251(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),252(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),2531,254intra_unsigned255);256257blocks += BLOCK_SIZE;258}259}260261XSelectInput(display, window, ExposureMask | KeyPressMask);262XMapWindow(display, window);263XSync(display, 0);264265/* Test NULL context */266assert(XvMCRenderSurface(display, NULL, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadContext);267/* Test NULL surface */268assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, NULL, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadSurface);269/* Test bad picture structure */270assert(XvMCRenderSurface(display, &context, 0, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == BadValue);271/* Test valid params */272assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == Success);273274/* Test NULL surface */275assert(XvMCPutSurface(display, NULL, window, 0, 0, INPUT_WIDTH, INPUT_HEIGHT, 0, 0, output_width, output_height, XVMC_FRAME_PICTURE) == XvMCBadSurface);276/* Test bad window */277/* XXX: X halts with a bad drawable for some reason, doesn't return BadDrawable as expected */278/*assert(XvMCPutSurface(display, &surface, 0, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == BadDrawable);*/279280if (prompt)281{282puts("Press any button to quit...");283284while (!quit)285{286if (XPending(display) > 0)287{288XEvent event;289290XNextEvent(display, &event);291292switch (event.type)293{294case Expose:295{296/* Test valid params */297assert298(299XvMCPutSurface300(301display, &surface, window,3020, 0, INPUT_WIDTH, INPUT_HEIGHT,3030, 0, output_width, output_height,304XVMC_FRAME_PICTURE305) == Success306);307break;308}309case KeyPress:310{311quit = 1;312break;313}314}315}316}317}318319assert(XvMCDestroyBlocks(display, &block_array) == Success);320assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success);321assert(XvMCDestroySurface(display, &surface) == Success);322assert(XvMCDestroyContext(display, &context) == Success);323324XvUngrabPort(display, port_num, CurrentTime);325XDestroyWindow(display, window);326XCloseDisplay(display);327328return 0;329}330331332