103b705cfSriastradh/*
203b705cfSriastradh * Copyright © 2009 Nokia Corporation
303b705cfSriastradh * Copyright © 2010 Movial Creative Technologies Oy
403b705cfSriastradh * Copyright © 2013 Intel Corporation
503b705cfSriastradh *
603b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a
703b705cfSriastradh * copy of this software and associated documentation files (the "Software"),
803b705cfSriastradh * to deal in the Software without restriction, including without limitation
903b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1003b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the
1103b705cfSriastradh * Software is furnished to do so, subject to the following conditions:
1203b705cfSriastradh *
1303b705cfSriastradh * The above copyright notice and this permission notice (including the next
1403b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the
1503b705cfSriastradh * Software.
1603b705cfSriastradh *
1703b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1803b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1903b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2003b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2103b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2203b705cfSriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2303b705cfSriastradh * DEALINGS IN THE SOFTWARE.
2403b705cfSriastradh */
2503b705cfSriastradh
2642542f5fSchristos#ifdef HAVE_CONFIG_H
2742542f5fSchristos#include "config.h"
2842542f5fSchristos#endif
2942542f5fSchristos
3003b705cfSriastradh#include <stdio.h>
3103b705cfSriastradh#include <stdlib.h>
3203b705cfSriastradh#include <string.h>
3303b705cfSriastradh#include <stdint.h>
3403b705cfSriastradh#include <stdbool.h>
3503b705cfSriastradh
3603b705cfSriastradh#include <X11/X.h>
3703b705cfSriastradh#include <X11/Xutil.h> /* for XDestroyImage */
3842542f5fSchristos#include <X11/Xlibint.h>
3942542f5fSchristos#include <X11/extensions/Xrender.h>
4042542f5fSchristos#if HAVE_MIT_SHM
4142542f5fSchristos#include <X11/extensions/XShm.h>
4242542f5fSchristos#if HAVE_X11_EXTENSIONS_SHMPROTO_H
4342542f5fSchristos#include <X11/extensions/shmproto.h>
4442542f5fSchristos#elif HAVE_X11_EXTENSIONS_SHMSTR_H
4542542f5fSchristos#include <X11/extensions/shmstr.h>
4642542f5fSchristos#else
4742542f5fSchristos#error Failed to find the right header for X11 MIT-SHM protocol definitions
4842542f5fSchristos#endif
4942542f5fSchristos#include <sys/ipc.h>
5042542f5fSchristos#include <sys/shm.h>
5142542f5fSchristos#endif
5203b705cfSriastradh#include <pixman.h> /* for pixman blt functions */
5303b705cfSriastradh
5403b705cfSriastradh#include "test.h"
5503b705cfSriastradh
5603b705cfSriastradhstatic const struct format {
5703b705cfSriastradh	const char *name;
5803b705cfSriastradh	pixman_format_code_t pixman_format;
5903b705cfSriastradh} formats[] = {
6003b705cfSriastradh	{ "a8r8g8b8", PIXMAN_a8r8g8b8 },
6103b705cfSriastradh	{ "x8r8g8b8", PIXMAN_x8r8g8b8 },
6203b705cfSriastradh	{ "a8", PIXMAN_a8 },
6303b705cfSriastradh	{ "a4", PIXMAN_a4 },
6403b705cfSriastradh	{ "a1", PIXMAN_a1 },
6503b705cfSriastradh};
6603b705cfSriastradh
6703b705cfSriastradhstatic const struct op {
6842542f5fSchristos	int value;
6903b705cfSriastradh	const char *name;
7003b705cfSriastradh} ops[] = {
7142542f5fSchristos	{ PictOpClear, "Clear" },
7242542f5fSchristos	{ PictOpSrc, "Src" },
7342542f5fSchristos	{ PictOpDst, "Dst" },
7442542f5fSchristos	{ PictOpOver, "Over" },
7542542f5fSchristos	{ PictOpOverReverse, "OverReverse" },
7642542f5fSchristos	{ PictOpIn, "In" },
7742542f5fSchristos	{ PictOpInReverse, "InReverse" },
7842542f5fSchristos	{ PictOpOut, "Out" },
7942542f5fSchristos	{ PictOpOutReverse, "OutReverse" },
8042542f5fSchristos	{ PictOpAtop, "Atop" },
8142542f5fSchristos	{ PictOpAtopReverse, "AtopReverse" },
8242542f5fSchristos	{ PictOpXor, "Xor" },
8342542f5fSchristos	{ PictOpAdd, "Add" },
8442542f5fSchristos	{ PictOpSaturate, "Saturate" },
8542542f5fSchristos	{ PictOpMultiply, "Multiply" },
8642542f5fSchristos	{ PictOpScreen, "Screen" },
8742542f5fSchristos	{ PictOpOverlay, "Overlay" },
8842542f5fSchristos	{ PictOpDarken, "Darken" },
8942542f5fSchristos	{ PictOpLighten, "Lighten" },
9042542f5fSchristos	{ PictOpColorDodge, "Dodge" },
9142542f5fSchristos	{ PictOpColorBurn, "Burn" },
9242542f5fSchristos	{ PictOpHardLight, "HardLight" },
9342542f5fSchristos	{ PictOpSoftLight, "SoftLight" },
9403b705cfSriastradh};
9503b705cfSriastradh
9642542f5fSchristosstatic Picture source_pixmap(struct test_display *t, struct test_target *target, int format)
9742542f5fSchristos{
9842542f5fSchristos	XRenderColor render_color[2] = {
9942542f5fSchristos		{ 0x8000, 0x8000, 0x8000, 0x8000 },
10042542f5fSchristos		{ 0xffff, 0xffff, 0xffff, 0xffff },
10142542f5fSchristos	};
10242542f5fSchristos	Pixmap pixmap;
10342542f5fSchristos	Picture picture;
10442542f5fSchristos
10542542f5fSchristos	pixmap = XCreatePixmap(t->dpy, t->root,
10642542f5fSchristos			       target->width, target->height,
10742542f5fSchristos			       PIXMAN_FORMAT_DEPTH(formats[format].pixman_format));
10842542f5fSchristos
10942542f5fSchristos	picture = XRenderCreatePicture(t->dpy, pixmap,
11042542f5fSchristos				       XRenderFindStandardFormat(t->dpy, format),
11142542f5fSchristos				       0, NULL);
11242542f5fSchristos	XFreePixmap(t->dpy, pixmap);
11342542f5fSchristos
11442542f5fSchristos	XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color[0],
11542542f5fSchristos			     0, 0, target->width, target->height/2);
11642542f5fSchristos	XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color[1],
11742542f5fSchristos			     0, target->height/2, target->width, target->height/2);
11842542f5fSchristos
11942542f5fSchristos	return picture;
12042542f5fSchristos}
12142542f5fSchristos
12242542f5fSchristosstatic Picture source_a8r8g8b8(struct test_display *t, struct test_target *target)
12342542f5fSchristos{
12442542f5fSchristos	return source_pixmap(t, target, 0);
12542542f5fSchristos}
12642542f5fSchristos
12742542f5fSchristosstatic Picture source_x8r8g8b8(struct test_display *t, struct test_target *target)
12842542f5fSchristos{
12942542f5fSchristos	return source_pixmap(t, target, 1);
13042542f5fSchristos}
13142542f5fSchristos
13242542f5fSchristosstatic Picture source_a8(struct test_display *t, struct test_target *target)
13342542f5fSchristos{
13442542f5fSchristos	return source_pixmap(t, target, 2);
13542542f5fSchristos}
13642542f5fSchristos
13742542f5fSchristosstatic Picture source_a4(struct test_display *t, struct test_target *target)
13842542f5fSchristos{
13942542f5fSchristos	return source_pixmap(t, target, 3);
14042542f5fSchristos}
14142542f5fSchristos
14242542f5fSchristosstatic Picture source_a1(struct test_display *t, struct test_target *target)
14342542f5fSchristos{
14442542f5fSchristos	return source_pixmap(t, target, 3);
14542542f5fSchristos}
14642542f5fSchristos
14742542f5fSchristosstatic Picture source_1x1r(struct test_display *t, struct test_target *target)
14803b705cfSriastradh{
14903b705cfSriastradh	XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 };
15042542f5fSchristos	XRenderPictureAttributes pa;
15142542f5fSchristos	Pixmap pixmap;
15242542f5fSchristos	Picture picture;
15342542f5fSchristos
15442542f5fSchristos	pa.repeat = RepeatNormal;
15542542f5fSchristos
15642542f5fSchristos	pixmap = XCreatePixmap(t->dpy, t->root, 1, 1, 32);
15742542f5fSchristos	picture = XRenderCreatePicture(t->dpy, pixmap,
15842542f5fSchristos				       XRenderFindStandardFormat(t->dpy, 0),
15942542f5fSchristos				       CPRepeat, &pa);
16042542f5fSchristos	XFreePixmap(t->dpy, pixmap);
16142542f5fSchristos
16242542f5fSchristos	XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color,
16342542f5fSchristos			     0, 0, 1, 1);
16442542f5fSchristos
16542542f5fSchristos	return picture;
16642542f5fSchristos}
16742542f5fSchristos
16842542f5fSchristosstatic Picture source_solid(struct test_display *t, struct test_target *target)
16942542f5fSchristos{
17042542f5fSchristos	XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 };
17142542f5fSchristos	return XRenderCreateSolidFill(t->dpy, &render_color);
17242542f5fSchristos}
17342542f5fSchristos
17442542f5fSchristosstatic Picture source_linear_horizontal(struct test_display *t, struct test_target *target)
17542542f5fSchristos{
17642542f5fSchristos	XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}};
17742542f5fSchristos	XFixed stops[2] = {0, 0xffff};
17842542f5fSchristos	XLinearGradient gradient = { {0, 0}, {target->width << 16, 0}};
17942542f5fSchristos
18042542f5fSchristos	return XRenderCreateLinearGradient(t->dpy, &gradient, stops, colors, 2);
18142542f5fSchristos}
18242542f5fSchristos
18342542f5fSchristosstatic Picture source_linear_vertical(struct test_display *t, struct test_target *target)
18442542f5fSchristos{
18542542f5fSchristos	XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}};
18642542f5fSchristos	XFixed stops[2] = {0, 0xffff};
18742542f5fSchristos	XLinearGradient gradient = { {0, 0}, {0, target->height << 16}};
18842542f5fSchristos
18942542f5fSchristos	return XRenderCreateLinearGradient(t->dpy, &gradient, stops, colors, 2);
19042542f5fSchristos}
19142542f5fSchristos
19242542f5fSchristosstatic Picture source_linear_diagonal(struct test_display *t, struct test_target *target)
19342542f5fSchristos{
19442542f5fSchristos	XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}};
19542542f5fSchristos	XFixed stops[2] = {0, 0xffff};
19642542f5fSchristos	XLinearGradient gradient = { {0, 0}, {target->width << 16, target->height << 16}};
19742542f5fSchristos
19842542f5fSchristos	return XRenderCreateLinearGradient(t->dpy, &gradient, stops, colors, 2);
19942542f5fSchristos}
20042542f5fSchristos
20142542f5fSchristosstatic Picture source_radial_concentric(struct test_display *t, struct test_target *target)
20242542f5fSchristos{
20342542f5fSchristos	XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}};
20442542f5fSchristos	XFixed stops[2] = {0, 0xffff};
20542542f5fSchristos	XRadialGradient gradient = {
20642542f5fSchristos		{
20742542f5fSchristos			((target->width << 16) + 1) / 2,
20842542f5fSchristos			((target->height << 16) + 1) / 2,
20942542f5fSchristos			0,
21042542f5fSchristos		},
21142542f5fSchristos		{
21242542f5fSchristos			((target->width << 16) + 1) / 2,
21342542f5fSchristos			((target->height << 16) + 1) / 2,
21442542f5fSchristos			target->width << 15,
21542542f5fSchristos		}
21642542f5fSchristos	};
21742542f5fSchristos
21842542f5fSchristos	return XRenderCreateRadialGradient(t->dpy, &gradient, stops, colors, 2);
21942542f5fSchristos}
22042542f5fSchristos
22142542f5fSchristosstatic Picture source_radial_generic(struct test_display *t, struct test_target *target)
22242542f5fSchristos{
22342542f5fSchristos	XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}};
22442542f5fSchristos	XFixed stops[2] = {0, 0xffff};
22542542f5fSchristos	XRadialGradient gradient = {
22642542f5fSchristos		{ 0, 0, target->width << 14, },
22742542f5fSchristos		{ target->width << 16, target->height << 16, target->width << 14, }
22842542f5fSchristos	};
22942542f5fSchristos
23042542f5fSchristos	return XRenderCreateRadialGradient(t->dpy, &gradient, stops, colors, 2);
23142542f5fSchristos}
23242542f5fSchristos
23342542f5fSchristos#if HAVE_MIT_SHM
23442542f5fSchristosstatic XShmSegmentInfo shmref, shmout;
23542542f5fSchristos
23642542f5fSchristosstatic void setup_shm(struct test *t)
23742542f5fSchristos{
23842542f5fSchristos	XShmSegmentInfo shm;
23942542f5fSchristos	int size;
24042542f5fSchristos
24142542f5fSchristos	shm.shmid = -1;
24242542f5fSchristos
24342542f5fSchristos	if (!(t->ref.has_shm_pixmaps && t->out.has_shm_pixmaps))
24442542f5fSchristos		return;
24542542f5fSchristos
24642542f5fSchristos	size = t->ref.width * t->ref.height * 4;
24742542f5fSchristos	size = (size + 4095) & -4096;
24842542f5fSchristos
24942542f5fSchristos	shm.shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0666);
25042542f5fSchristos	if (shm.shmid == -1)
25142542f5fSchristos		return;
25242542f5fSchristos
25342542f5fSchristos	shm.shmaddr = shmat(shm.shmid, 0, 0);
25442542f5fSchristos	if (shm.shmaddr == (char *) -1) {
25542542f5fSchristos		shmctl(shm.shmid, IPC_RMID, NULL);
25642542f5fSchristos		shm.shmid = -1;
25742542f5fSchristos		return;
25842542f5fSchristos	}
25942542f5fSchristos
26042542f5fSchristos	shm.readOnly = False;
26142542f5fSchristos
26242542f5fSchristos	shmref = shm;
26342542f5fSchristos	XShmAttach(t->ref.dpy, &shmref);
26442542f5fSchristos	XSync(t->ref.dpy, True);
26542542f5fSchristos
26642542f5fSchristos	shmout = shm;
26742542f5fSchristos	XShmAttach(t->out.dpy, &shmout);
26842542f5fSchristos	XSync(t->out.dpy, True);
26942542f5fSchristos}
27042542f5fSchristos
27142542f5fSchristosstatic Picture source_shm(struct test_display *t, struct test_target *target)
27242542f5fSchristos{
27342542f5fSchristos	XShmSegmentInfo *shm = t->target == REF ? &shmref : &shmout;
27403b705cfSriastradh	Pixmap pixmap;
27503b705cfSriastradh	Picture picture;
27642542f5fSchristos	int size;
27742542f5fSchristos
27842542f5fSchristos	if (shm->shmid == -1)
27942542f5fSchristos		return 0;
28042542f5fSchristos
28142542f5fSchristos	pixmap = XShmCreatePixmap(t->dpy, t->root,
28242542f5fSchristos				  shm->shmaddr, shm,
28342542f5fSchristos				  target->width, target->height, 32);
28442542f5fSchristos
28542542f5fSchristos	picture = XRenderCreatePicture(t->dpy, pixmap,
28642542f5fSchristos				       XRenderFindStandardFormat(t->dpy, 0),
28742542f5fSchristos				       0, NULL);
28842542f5fSchristos	XFreePixmap(t->dpy, pixmap);
28942542f5fSchristos
29042542f5fSchristos	size = target->width * target->height * 4;
29142542f5fSchristos	memset(shm->shmaddr, 0x80, size/2);
29242542f5fSchristos	memset(shm->shmaddr+size/2, 0xff, size/2);
29342542f5fSchristos
29442542f5fSchristos	return picture;
29542542f5fSchristos}
29642542f5fSchristos#else
29742542f5fSchristosstatic void setup_shm(struct test *t) { }
29842542f5fSchristosstatic Picture source_shm(struct test_display *t, struct test_target *target) { return 0; }
29942542f5fSchristos#endif
30042542f5fSchristos
30142542f5fSchristosstatic const struct {
30242542f5fSchristos	Picture (*create)(struct test_display *, struct test_target *);
30342542f5fSchristos	const char *name;
30442542f5fSchristos} source[] = {
30542542f5fSchristos	{ source_a8r8g8b8, "a8r8g8b8 pixmap" },
30642542f5fSchristos	{ source_x8r8g8b8, "x8r8g8b8 pixmap" },
30742542f5fSchristos	{ source_a8, "a8 pixmap" },
30842542f5fSchristos	{ source_a4, "a4 pixmap" },
30942542f5fSchristos	{ source_a1, "a1 pixmap" },
31042542f5fSchristos	{ source_1x1r, "a8r8g8b8 1x1R pixmap" },
31142542f5fSchristos	{ source_solid, "solid" },
31242542f5fSchristos	{ source_shm, "a8r8g8b8 shm" },
31342542f5fSchristos	{ source_linear_horizontal, "linear (horizontal gradient)" },
31442542f5fSchristos	{ source_linear_vertical, "linear (vertical gradient)" },
31542542f5fSchristos	{ source_linear_diagonal, "linear (diagonal gradient)" },
31642542f5fSchristos	{ source_radial_concentric, "radial (concentric)" },
31742542f5fSchristos	{ source_radial_generic, "radial (generic)" },
31842542f5fSchristos};
31942542f5fSchristos
32042542f5fSchristosstatic double _bench_source(struct test_display *t, enum target target_type,
32142542f5fSchristos			    int op, int src, int loops)
32242542f5fSchristos{
32342542f5fSchristos	XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 };
32442542f5fSchristos	struct test_target target;
32542542f5fSchristos	Picture picture;
32603b705cfSriastradh	struct timespec tv;
32703b705cfSriastradh	double elapsed;
32803b705cfSriastradh
32903b705cfSriastradh	test_target_create_render(t, target_type, &target);
33003b705cfSriastradh	XRenderFillRectangle(t->dpy, PictOpClear, target.picture, &render_color,
33103b705cfSriastradh			     0, 0, target.width, target.height);
33203b705cfSriastradh
33342542f5fSchristos	picture = source[src].create(t, &target);
33442542f5fSchristos	if (picture) {
33542542f5fSchristos		test_timer_start(t, &tv);
33642542f5fSchristos		while (loops--)
33742542f5fSchristos			XRenderComposite(t->dpy, op,
33842542f5fSchristos					 picture, 0, target.picture,
33942542f5fSchristos					 0, 0,
34042542f5fSchristos					 0, 0,
34142542f5fSchristos					 0, 0,
34242542f5fSchristos					 target.width, target.height);
34342542f5fSchristos		elapsed = test_timer_stop(t, &tv);
34442542f5fSchristos		XRenderFreePicture(t->dpy, picture);
34542542f5fSchristos	} else
34642542f5fSchristos		elapsed = -1;
34703b705cfSriastradh
34842542f5fSchristos	test_target_destroy_render(t, &target);
34942542f5fSchristos
35042542f5fSchristos	return elapsed;
35142542f5fSchristos}
35242542f5fSchristos
35342542f5fSchristosstatic void bench_source(struct test *t, enum target target, int op, int src)
35442542f5fSchristos{
35542542f5fSchristos	double out, ref;
35642542f5fSchristos
35742542f5fSchristos	fprintf(stdout, "%28s with %s: ", source[src].name, ops[op].name);
35842542f5fSchristos	fflush(stdout);
35942542f5fSchristos
36042542f5fSchristos	op = ops[op].value;
36142542f5fSchristos
36242542f5fSchristos	ref = _bench_source(&t->ref, target, op, src, 1000);
36342542f5fSchristos	if (ref < 0) {
36442542f5fSchristos		fprintf(stdout, "SKIP\n");
36542542f5fSchristos		return;
36642542f5fSchristos	}
36742542f5fSchristos	fprintf(stdout, "ref=%f, ", ref);
36842542f5fSchristos	fflush(stdout);
36942542f5fSchristos
37042542f5fSchristos	out = _bench_source(&t->out, target, op, src, 1000);
37142542f5fSchristos	if (out < 0) {
37242542f5fSchristos		fprintf(stdout, "SKIP\n");
37342542f5fSchristos		return;
37442542f5fSchristos	}
37542542f5fSchristos
37642542f5fSchristos	fprintf(stdout, "out=%f\n", out);
37742542f5fSchristos}
37842542f5fSchristos
37942542f5fSchristosstatic double _bench_mask(struct test_display *t, enum target target_type,
38042542f5fSchristos			    int op, int src, int mask, int loops)
38142542f5fSchristos{
38242542f5fSchristos	XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 };
38342542f5fSchristos	struct test_target target;
38442542f5fSchristos	Picture ps, pm;
38542542f5fSchristos	struct timespec tv;
38642542f5fSchristos	double elapsed;
38742542f5fSchristos
38842542f5fSchristos	test_target_create_render(t, target_type, &target);
38942542f5fSchristos	XRenderFillRectangle(t->dpy, PictOpClear, target.picture, &render_color,
39003b705cfSriastradh			     0, 0, target.width, target.height);
39103b705cfSriastradh
39242542f5fSchristos	ps = source[src].create(t, &target);
39342542f5fSchristos	pm = source[mask].create(t, &target);
39442542f5fSchristos	if (ps && pm) {
39542542f5fSchristos		test_timer_start(t, &tv);
39642542f5fSchristos		while (loops--)
39742542f5fSchristos			XRenderComposite(t->dpy, op,
39842542f5fSchristos					 ps, pm, target.picture,
39942542f5fSchristos					 0, 0,
40042542f5fSchristos					 0, 0,
40142542f5fSchristos					 0, 0,
40242542f5fSchristos					 target.width, target.height);
40342542f5fSchristos		elapsed = test_timer_stop(t, &tv);
40442542f5fSchristos	} else
40542542f5fSchristos		elapsed = -1;
40642542f5fSchristos
40742542f5fSchristos	if (ps)
40842542f5fSchristos		XRenderFreePicture(t->dpy, ps);
40942542f5fSchristos	if (pm)
41042542f5fSchristos		XRenderFreePicture(t->dpy, pm);
41142542f5fSchristos
41203b705cfSriastradh	test_target_destroy_render(t, &target);
41303b705cfSriastradh
41403b705cfSriastradh	return elapsed;
41503b705cfSriastradh}
41603b705cfSriastradh
41742542f5fSchristosstatic void bench_mask(struct test *t, enum target target, int op, int src, int mask)
41803b705cfSriastradh{
41942542f5fSchristos	double out, ref;
42003b705cfSriastradh
42142542f5fSchristos	fprintf(stdout, "%28s In %28s with %s: ",
42242542f5fSchristos		source[src].name, source[mask].name, ops[op].name);
42342542f5fSchristos	fflush(stdout);
42403b705cfSriastradh
42542542f5fSchristos	op = ops[op].value;
42642542f5fSchristos
42742542f5fSchristos	ref = _bench_mask(&t->ref, target, op, src, mask, 1000);
42842542f5fSchristos	if (ref < 0) {
42942542f5fSchristos		fprintf(stdout, "SKIP\n");
43042542f5fSchristos		return;
43142542f5fSchristos	}
43242542f5fSchristos	fprintf(stdout, "ref=%f, ", ref);
43342542f5fSchristos	fflush(stdout);
43442542f5fSchristos
43542542f5fSchristos	out = _bench_mask(&t->out, target, op, src, mask, 1000);
43642542f5fSchristos	if (out < 0) {
43742542f5fSchristos		fprintf(stdout, "SKIP\n");
43842542f5fSchristos		return;
43942542f5fSchristos	}
44042542f5fSchristos
44142542f5fSchristos	fprintf(stdout, "out=%f\n", out);
44203b705cfSriastradh}
44303b705cfSriastradh
44403b705cfSriastradhint main(int argc, char **argv)
44503b705cfSriastradh{
44603b705cfSriastradh	struct test test;
44742542f5fSchristos	unsigned op, src, mask;
44803b705cfSriastradh
44903b705cfSriastradh	test_init(&test, argc, argv);
45003b705cfSriastradh
45142542f5fSchristos	setup_shm(&test);
45242542f5fSchristos
45303b705cfSriastradh	for (op = 0; op < sizeof(ops)/sizeof(ops[0]); op++) {
45442542f5fSchristos		for (src = 0; src < sizeof(source)/sizeof(source[0]); src++)
45542542f5fSchristos			bench_source(&test, ROOT, op, src);
45642542f5fSchristos		fprintf (stdout, "\n");
45742542f5fSchristos
45842542f5fSchristos		for (src = 0; src < sizeof(source)/sizeof(source[0]); src++)
45942542f5fSchristos			for (mask = 0; mask < sizeof(source)/sizeof(source[0]); mask++)
46042542f5fSchristos				bench_mask(&test, ROOT, op, src, mask);
46103b705cfSriastradh		fprintf (stdout, "\n");
46203b705cfSriastradh	}
46303b705cfSriastradh
46403b705cfSriastradh	return 0;
46503b705cfSriastradh}
466