test: Add a very basic blt benchmark
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
9c80a0337e
commit
82dc91e8c2
|
|
@ -13,3 +13,4 @@ render-copyarea
|
|||
render-copyarea-size
|
||||
render-copy-alphaless
|
||||
mixed-stress
|
||||
lowlevel-blt-bench
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ stress_TESTS = \
|
|||
|
||||
check_PROGRAMS = $(stress_TESTS)
|
||||
|
||||
noinst_PROGRAMS = lowlevel-blt-bench
|
||||
|
||||
AM_CFLAGS = @CWARNFLAGS@ @X11_CFLAGS@ @DRM_CFLAGS@
|
||||
LDADD = libtest.la @X11_LIBS@ -lXfixes @DRM_LIBS@ -lrt
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright © 2009 Nokia Corporation
|
||||
* Copyright © 2010 Movial Creative Technologies Oy
|
||||
* Copyright © 2013 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xutil.h> /* for XDestroyImage */
|
||||
#include <pixman.h> /* for pixman blt functions */
|
||||
|
||||
#include "test.h"
|
||||
|
||||
static const struct format {
|
||||
const char *name;
|
||||
pixman_format_code_t pixman_format;
|
||||
} formats[] = {
|
||||
{ "a8r8g8b8", PIXMAN_a8r8g8b8 },
|
||||
{ "x8r8g8b8", PIXMAN_x8r8g8b8 },
|
||||
{ "a8", PIXMAN_a8 },
|
||||
{ "a4", PIXMAN_a4 },
|
||||
{ "a1", PIXMAN_a1 },
|
||||
};
|
||||
|
||||
static const struct op {
|
||||
const char *name;
|
||||
} ops[] = {
|
||||
[PictOpClear] = { "Clear" },
|
||||
[PictOpSrc] = { "Src" },
|
||||
[PictOpDst] = { "Dst" },
|
||||
[PictOpOver] = { "Over" },
|
||||
[PictOpOverReverse] = { "OverReverse" },
|
||||
[PictOpIn] = { "In" },
|
||||
[PictOpInReverse] = { "InReverse" },
|
||||
[PictOpOut] = { "Out" },
|
||||
[PictOpOutReverse] = { "OutReverse" },
|
||||
[PictOpAtop] = { "Atop" },
|
||||
[PictOpAtopReverse] = { "AtopReverse" },
|
||||
[PictOpXor] = { "Xor" },
|
||||
[PictOpAdd] = { "Add" },
|
||||
[PictOpSaturate] = { "Saturate" },
|
||||
};
|
||||
|
||||
static double _bench(struct test_display *t, enum target target_type,
|
||||
int op, int src_format,
|
||||
int loops)
|
||||
{
|
||||
XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 };
|
||||
struct test_target target;
|
||||
Pixmap pixmap;
|
||||
Picture picture;
|
||||
struct timespec tv;
|
||||
double elapsed;
|
||||
|
||||
test_target_create_render(t, target_type, &target);
|
||||
XRenderFillRectangle(t->dpy, PictOpClear, target.picture, &render_color,
|
||||
0, 0, target.width, target.height);
|
||||
|
||||
pixmap = XCreatePixmap(t->dpy, t->root,
|
||||
target.width, target.height,
|
||||
PIXMAN_FORMAT_DEPTH(formats[src_format].pixman_format));
|
||||
|
||||
picture = XRenderCreatePicture(t->dpy, pixmap,
|
||||
XRenderFindStandardFormat(t->dpy, src_format),
|
||||
0, NULL);
|
||||
XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color,
|
||||
0, 0, target.width, target.height);
|
||||
|
||||
test_timer_start(t, &tv);
|
||||
while (loops--)
|
||||
XRenderComposite(t->dpy, op,
|
||||
picture, 0, target.picture,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
target.width, target.height);
|
||||
elapsed = test_timer_stop(t, &tv);
|
||||
|
||||
XRenderFreePicture(t->dpy, picture);
|
||||
XFreePixmap(t->dpy, pixmap);
|
||||
test_target_destroy_render(t, &target);
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
static void bench(struct test *t, enum target target, int op, int sf)
|
||||
{
|
||||
double real, ref;
|
||||
|
||||
ref = _bench(&t->ref, target, op, sf, 1000);
|
||||
real = _bench(&t->real, target, op, sf, 1000);
|
||||
|
||||
fprintf (stdout, "Testing %s with %s: ref=%f, real=%f\n",
|
||||
formats[sf].name, ops[op].name, ref, real);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct test test;
|
||||
int op, sf;
|
||||
|
||||
test_init(&test, argc, argv);
|
||||
|
||||
for (op = 0; op < sizeof(ops)/sizeof(ops[0]); op++) {
|
||||
for (sf = 0; sf < sizeof(formats)/sizeof(formats[0]); sf++)
|
||||
bench(&test, ROOT, op, sf);
|
||||
fprintf (stdout, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
#define TEST_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
|
@ -107,6 +109,9 @@ static inline uint32_t color(uint8_t red, uint8_t green, uint8_t blue, uint8_t a
|
|||
return alpha << 24 | ra >> 8 << 16 | ga >> 8 << 8 | ba >> 8;
|
||||
}
|
||||
|
||||
void test_timer_start(struct test_display *t, struct timespec *tv);
|
||||
double test_timer_stop(struct test_display *t, struct timespec *tv);
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -148,3 +148,20 @@ void test_init(struct test *test, int argc, char **argv)
|
|||
memset(test, 0, sizeof(*test));
|
||||
test_get_displays(argc, argv, &test->real, &test->ref);
|
||||
}
|
||||
|
||||
void test_timer_start(struct test_display *t, struct timespec *tv)
|
||||
{
|
||||
clock_gettime(CLOCK_MONOTONIC, tv);
|
||||
}
|
||||
|
||||
double test_timer_stop(struct test_display *t, struct timespec *tv)
|
||||
{
|
||||
XImage *image;
|
||||
struct timespec now;
|
||||
|
||||
image = XGetImage(t->dpy, t->root, 0, 0, 1, 1, AllPlanes, ZPixmap);
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
XDestroyImage(image);
|
||||
|
||||
return (now.tv_sec - tv->tv_sec) + 1e-9*(now.tv_nsec - tv->tv_nsec);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue