test_rendering.c revision dcf8ee7d6ac89bb2a9d608618a51604a3c78fe96
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**************************************************************************
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2009 Younes Manton.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All Rights Reserved.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "Software"), to deal in the Software without restriction, including
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * without limitation the rights to use, copy, modify, merge, publish,
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distribute, sub license, and/or sell copies of the Software, and to
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * permit persons to whom the Software is furnished to do so, subject to
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the following conditions:
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above copyright notice and this permission notice (including the
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * next paragraph) shall be included in all copies or substantial portions
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * of the Software.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) **************************************************************************/
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <error.h>
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testlib.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BLOCK_WIDTH			8
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BLOCK_HEIGHT			8
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BLOCK_SIZE			(BLOCK_WIDTH * BLOCK_HEIGHT)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MACROBLOCK_WIDTH		16
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MACROBLOCK_HEIGHT		16
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MACROBLOCK_WIDTH_IN_BLOCKS	(MACROBLOCK_WIDTH / BLOCK_WIDTH)
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MACROBLOCK_HEIGHT_IN_BLOCKS	(MACROBLOCK_HEIGHT / BLOCK_HEIGHT)
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define BLOCKS_PER_MACROBLOCK		6
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define INPUT_WIDTH			64
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INPUT_HEIGHT			64
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INPUT_WIDTH_IN_MACROBLOCKS	(INPUT_WIDTH / MACROBLOCK_WIDTH)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INPUT_HEIGHT_IN_MACROBLOCKS	(INPUT_HEIGHT / MACROBLOCK_HEIGHT)
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define NUM_MACROBLOCKS			(INPUT_WIDTH_IN_MACROBLOCKS * INPUT_HEIGHT_IN_MACROBLOCKS)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define DEFAULT_OUTPUT_WIDTH		INPUT_WIDTH
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define DEFAULT_OUTPUT_HEIGHT		INPUT_HEIGHT
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define DEFAULT_ACCEPTABLE_ERR		0.01
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int fail = 0;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*output_width = DEFAULT_OUTPUT_WIDTH;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*output_height = DEFAULT_OUTPUT_HEIGHT;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*acceptable_error = DEFAULT_ACCEPTABLE_ERR;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*prompt = 1;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 1; i < argc && !fail; ++i)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!strcmp(argv[i], "-w"))
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (sscanf(argv[++i], "%u", output_width) != 1)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				fail = 1;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else if (!strcmp(argv[i], "-h"))
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (sscanf(argv[++i], "%u", output_height) != 1)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				fail = 1;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else if (!strcmp(argv[i], "-e"))
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (sscanf(argv[++i], "%lf", acceptable_error) != 1)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				fail = 1;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else if (strcmp(argv[i], "-n"))
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			*prompt = 0;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			fail = 1;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (fail)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		error
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			1, 0,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"Bad argument.\n"
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"\n"
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)			"Usage: %s [options]\n"
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"\t-w <width>\tOutput width\n"
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"\t-h <height>\tOutput height\n"
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"\t-e <error>\tAcceptable margin of error per pixel, from 0 to 1\n"
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"\t-n\tDon't prompt for quit\n",
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			argv[0]
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void Gradient(short *block, unsigned int start, unsigned int stop, int horizontal, unsigned int intra_unsigned)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int x, y;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int range = stop - start;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (horizontal)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (y = 0; y < BLOCK_HEIGHT; ++y)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			for (x = 0; x < BLOCK_WIDTH; ++x) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				*block = (short)(start + range * (x / (float)(BLOCK_WIDTH - 1)));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (intra_unsigned)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					*block += 1 << 10;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				block++;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (y = 0; y < BLOCK_HEIGHT; ++y)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			for (x = 0; x < BLOCK_WIDTH; ++x) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				*block = (short)(start + range * (y / (float)(BLOCK_WIDTH - 1)));
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (intra_unsigned)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					*block += 1 << 10;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				block++;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int		output_width;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int		output_height;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	double			acceptable_error;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int			prompt;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	Display			*display;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	Window			root, window;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const unsigned int	mc_types[] = {XVMC_MOCOMP | XVMC_MPEG_2};
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XvPortID		port_num;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int			surface_type_id;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int		is_overlay, intra_unsigned;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int			colorkey;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XvMCContext		context;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XvMCSurface		surface;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XvMCBlockArray		block_array;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XvMCMacroBlockArray	mb_array;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int			mbx, mby, bx, by;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XvMCMacroBlock		*mb;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	short			*blocks;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int			quit = 0;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ParseArgs(argc, argv, &output_width, &output_height, &acceptable_error, &prompt);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	display = XOpenDisplay(NULL);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!GetPort
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		display,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		INPUT_WIDTH,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		INPUT_HEIGHT,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		XVMC_CHROMA_FORMAT_420,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		mc_types,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sizeof(mc_types)/sizeof(*mc_types),
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&port_num,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&surface_type_id,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&is_overlay,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&intra_unsigned
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	))
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		XCloseDisplay(display);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		error(1, 0, "Error, unable to find a good port.\n");
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)	if (is_overlay)
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)	{
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)		Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)		XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)	}
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)	root = XDefaultRootWindow(display);
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)	window = XCreateSimpleWindow(display, root, 0, 0, output_width, output_height, 0, 0, colorkey);
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)	assert(XvMCCreateContext(display, port_num, surface_type_id, INPUT_WIDTH, INPUT_HEIGHT, XVMC_DIRECT, &context) == Success);
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)	assert(XvMCCreateSurface(display, &context, &surface) == Success);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	assert(XvMCCreateBlocks(display, &context, NUM_MACROBLOCKS * BLOCKS_PER_MACROBLOCK, &block_array) == Success);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	assert(XvMCCreateMacroBlocks(display, &context, NUM_MACROBLOCKS, &mb_array) == Success);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	mb = mb_array.macro_blocks;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	blocks = block_array.blocks;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
191	for (mby = 0; mby < INPUT_HEIGHT_IN_MACROBLOCKS; ++mby)
192		for (mbx = 0; mbx < INPUT_WIDTH_IN_MACROBLOCKS; ++mbx)
193		{
194			mb->x = mbx;
195			mb->y = mby;
196			mb->macroblock_type = XVMC_MB_TYPE_INTRA;
197			/*mb->motion_type = ;*/
198			/*mb->motion_vertical_field_select = ;*/
199			mb->dct_type = XVMC_DCT_TYPE_FRAME;
200			/*mb->PMV[0][0][0] = ;
201			mb->PMV[0][0][1] = ;
202			mb->PMV[0][1][0] = ;
203			mb->PMV[0][1][1] = ;
204			mb->PMV[1][0][0] = ;
205			mb->PMV[1][0][1] = ;
206			mb->PMV[1][1][0] = ;
207			mb->PMV[1][1][1] = ;*/
208			mb->index = (mby * INPUT_WIDTH_IN_MACROBLOCKS + mbx) * BLOCKS_PER_MACROBLOCK;
209			mb->coded_block_pattern = 0x3F;
210
211			mb++;
212
213			for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS; ++by)
214				for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS; ++bx)
215				{
216					const int start = 16, stop = 235, range = stop - start;
217
218					Gradient
219					(
220						blocks,
221						(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
222						(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
223						1,
224						intra_unsigned
225					);
226
227					blocks += BLOCK_SIZE;
228				}
229
230			for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS / 2; ++by)
231				for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS / 2; ++bx)
232				{
233					const int start = 16, stop = 240, range = stop - start;
234
235					Gradient
236					(
237						blocks,
238						(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
239						(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
240						1,
241						intra_unsigned
242					);
243
244					blocks += BLOCK_SIZE;
245
246					Gradient
247					(
248						blocks,
249						(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
250						(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
251						1,
252						intra_unsigned
253					);
254
255					blocks += BLOCK_SIZE;
256				}
257		}
258
259	XSelectInput(display, window, ExposureMask | KeyPressMask);
260	XMapWindow(display, window);
261	XSync(display, 0);
262
263	/* Test NULL context */
264	assert(XvMCRenderSurface(display, NULL, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadContext);
265	/* Test NULL surface */
266	assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, NULL, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadSurface);
267	/* Test bad picture structure */
268	assert(XvMCRenderSurface(display, &context, 0, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == BadValue);
269	/* Test valid params */
270	assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == Success);
271
272	/* Test NULL surface */
273	assert(XvMCPutSurface(display, NULL, window, 0, 0, INPUT_WIDTH, INPUT_HEIGHT, 0, 0, output_width, output_height, XVMC_FRAME_PICTURE) == XvMCBadSurface);
274	/* Test bad window */
275	/* XXX: X halts with a bad drawable for some reason, doesn't return BadDrawable as expected */
276	/*assert(XvMCPutSurface(display, &surface, 0, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == BadDrawable);*/
277
278	if (prompt)
279	{
280		puts("Press any button to quit...");
281
282		while (!quit)
283		{
284			if (XPending(display) > 0)
285			{
286				XEvent event;
287
288				XNextEvent(display, &event);
289
290				switch (event.type)
291				{
292					case Expose:
293					{
294						/* Test valid params */
295						assert
296						(
297							XvMCPutSurface
298							(
299								display, &surface, window,
300								0, 0, INPUT_WIDTH, INPUT_HEIGHT,
301								0, 0, output_width, output_height,
302								XVMC_FRAME_PICTURE
303							) == Success
304						);
305						break;
306					}
307					case KeyPress:
308					{
309						quit = 1;
310						break;
311					}
312				}
313			}
314		}
315	}
316
317	assert(XvMCDestroyBlocks(display, &block_array) == Success);
318	assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success);
319	assert(XvMCDestroySurface(display, &surface) == Success);
320	assert(XvMCDestroyContext(display, &context) == Success);
321
322	XvUngrabPort(display, port_num, CurrentTime);
323	XDestroyWindow(display, window);
324	XCloseDisplay(display);
325
326	return 0;
327}
328