summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-01-12 17:22:03 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-01-12 17:22:03 +1100
commitc48266b56e7da69fe94785b62ac275517cf33f97 (patch)
tree97f26594d116f2fc0f960f138da5e96add53a773
parent262cbe9e5fa12f8b591756903511d0e15a96185e (diff)
Add missing twin_feature.c
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--libtwin/twin_feature.c72
-rw-r--r--twin_demos/twinperf.c121
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;
+}