diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2007-01-12 17:22:03 +1100 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2007-01-12 17:22:03 +1100 |
commit | c48266b56e7da69fe94785b62ac275517cf33f97 (patch) | |
tree | 97f26594d116f2fc0f960f138da5e96add53a773 | |
parent | 262cbe9e5fa12f8b591756903511d0e15a96185e (diff) |
Add missing twin_feature.c
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | libtwin/twin_feature.c | 72 | ||||
-rw-r--r-- | twin_demos/twinperf.c | 121 |
2 files changed, 193 insertions, 0 deletions
diff --git a/libtwin/twin_feature.c b/libtwin/twin_feature.c new file mode 100644 index 0000000..ceba5ab --- /dev/null +++ b/libtwin/twin_feature.c @@ -0,0 +1,72 @@ +/* + * Linux fbdev driver for Twin + * + * Copyright 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org> + * + * This Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Twin Library; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <signal.h> +#include <setjmp.h> + +#include "twinint.h" + +static unsigned int _twin_features; + +#ifdef HAVE_ALTIVEC + +static jmp_buf _twin_feature_jmpbuf; + +static void illegal_instruction(int sig) +{ + longjmp(_twin_feature_jmpbuf, 1); +} + + +static int _twin_have_altivec(void) +{ + volatile int altivec = 0; + void (*handler)(int sig); + + handler = signal(SIGILL, illegal_instruction); + if ( setjmp(_twin_feature_jmpbuf) == 0 ) { + asm volatile ("mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" + : + : "r" (-1)); + altivec = 1; + } + signal(SIGILL, handler); + + return altivec; +} + +#else +#define _twin_have_altivec() +#endif /* HAVE_ALTIVEC */ + +int twin_has_feature(unsigned int feature) +{ + return (_twin_features & feature) != 0; +} + +void twin_feature_init(void) +{ + if (_twin_have_altivec()) + _twin_features |= TWIN_FEATURE_ALTIVEC; + + _twin_draw_set_features(); +} diff --git a/twin_demos/twinperf.c b/twin_demos/twinperf.c new file mode 100644 index 0000000..c1730f4 --- /dev/null +++ b/twin_demos/twinperf.c @@ -0,0 +1,121 @@ +#include <stdio.h> +#include <assert.h> +#include <sys/time.h> +#include <time.h> + +#include "twin.h" +#include "twin_png.h" + +#define TEST_PIX_WIDTH 1200 +#define TEST_PIX_HEIGHT 800 + + +twin_pixmap_t *src32, *dst32, *msk; +int twidth, theight, titers; + +static void test_argb32_source_argb32(void) +{ + twin_operand_t srco; + + srco.source_kind = TWIN_PIXMAP; + srco.u.pixmap = src32; + twin_composite(dst32, 0, 0, &srco, 0, 0, NULL, 0, 0, TWIN_SOURCE, + twidth, theight); +} + +static void test_argb32_over_argb32(void) +{ + twin_operand_t srco; + + srco.source_kind = TWIN_PIXMAP; + srco.u.pixmap = src32; + twin_composite(dst32, 0, 0, &srco, 0, 0, NULL, 0, 0, TWIN_OVER, + twidth, theight); +} + +static void do_test(const char *name, void (*test)(void)) +{ + struct timeval start, end; + unsigned long long sus, eus; + char spc[128]; + char *s; + int i; + + printf("%s", name); + + gettimeofday(&start, NULL); + for (i = 0; i < titers; i++) + test(); + gettimeofday(&end, NULL); + sus = (unsigned long long)start.tv_sec * 1000000ull + start.tv_usec; + eus = (unsigned long long)end.tv_sec * 1000000ull + end.tv_usec; + + s = spc; + for (i = strlen(name); i <40; i++) + *(s++) = ' '; + *s = 0; + printf("%s %f sec\n", spc, ((float)(eus - sus)) / 1000000.0); +} + +#define DO_TEST(name) do_test(#name, test_##name) + +static void do_tests(int width, int height, int iters) +{ + twidth = width; + theight = height; + titers = iters; + + DO_TEST(argb32_source_argb32); + DO_TEST(argb32_over_argb32); +} + +static void do_all_tests(const char *title) +{ + printf("* %s, 10x10x1000000 :\n", title); + do_tests(10, 10, 1000000); + + printf("* %s, 100x100x20000 :\n", title); + do_tests(100, 100, 20000); + + printf("* %s, 200x200x10000 :\n", title); + do_tests(200, 200, 10000); + + printf("* %s, 1200x800x200 :\n", title); + do_tests(1200, 800, 200); + + printf("\n"); +} + +int main(void) +{ + printf("loading test pixmaps...\n"); + + /* Create some test pixmaps */ + src32 = twin_png_to_pixmap("twinperf-src32.png", TWIN_ARGB32); + assert(src32); + dst32 = twin_pixmap_create(TWIN_ARGB32, + TEST_PIX_WIDTH, TEST_PIX_HEIGHT); + assert(dst32); + +#if 0 + msk = twin_pixmap_create(TWIN_A8, + TEST_PIX_WIDTH, TEST_PIX_HEIGHT); + assert(msk); +#endif + + /* fill pixmaps */ + twin_fill(dst32, 0x80112233, TWIN_SOURCE, 0, 0, + TEST_PIX_WIDTH, TEST_PIX_HEIGHT); + + + /* pre-touch data */ + test_argb32_source_argb32(); + + do_all_tests("No features"); + + twin_feature_init(); + + do_all_tests("All features"); + + return 0; +} |