gegl r2477 - in trunk: . gegl operations operations/common operations/generated



Author: ok
Date: Sun Jun 15 22:41:20 2008
New Revision: 2477
URL: http://svn.gnome.org/viewvc/gegl?rev=2477&view=rev

Log:
Extended the gegl-chanting and the build system to easily allow
defining an alternate process function that will be compiled to mmx
and sse by gcc, coupled with runtime cpu detection at class init time
to determine which variant to use.
* configure.ac: make USE_SSE available to makefiles.
* gegl/Makefile.am: install gegl-cpuaccel.h
* gegl/gegl-chant.h: added logic to detect various SIMD compile modes,
generating different .o 's based on compiler flags.
* gegl/gegl-plugin.h: include gegl-cpuaccel.h
* operations/Makefile-operations.am: added separete recipe for
compiling .c files that contains the string GEGL_SIMD.
* operations/common/brightness-contrast.c: 
* operations/common/invert.c: 
* operations/generated/other-blend.rb:
* operations/generated/svg-12-porter-duff.rb: The rest, updated to
specify their SIMD code using GEGL_SIMD.


Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/gegl/Makefile.am
   trunk/gegl/gegl-chant.h
   trunk/gegl/gegl-plugin.h
   trunk/operations/Makefile-operations.am
   trunk/operations/common/brightness-contrast.c
   trunk/operations/common/invert.c
   trunk/operations/generated/other-blend.rb
   trunk/operations/generated/svg-12-porter-duff.rb

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Sun Jun 15 22:41:20 2008
@@ -410,7 +410,7 @@
   AC_SUBST(SSE_EXTRA_CFLAGS)
 fi
 
-CFLAGS="$CFLAGS $SSE_EXTRA_CFLAGS"
+AM_CONDITIONAL(USE_SSE, test "x$enable_sse" = "xyes")
 
 
 ###############################
@@ -850,6 +850,7 @@
   Build website:  $have_asciidoc
   SIMD:           sse:$enable_sse mmx:$enable_mmx
 
+
 Optional dependencies:
   GTK+:           $have_gtk
   GIO:            $have_gio

Modified: trunk/gegl/Makefile.am
==============================================================================
--- trunk/gegl/Makefile.am	(original)
+++ trunk/gegl/Makefile.am	Sun Jun 15 22:41:20 2008
@@ -66,6 +66,7 @@
     gegl-utils.h			\
     gegl-chant.h			\
     gegl-simd.h				\
+    gegl-cpuaccel.h			\
     gegl-plugin.h			\
     buffer/gegl-buffer.h		\
     property-types/gegl-paramspecs.h	\

Modified: trunk/gegl/gegl-chant.h
==============================================================================
--- trunk/gegl/gegl-chant.h	(original)
+++ trunk/gegl/gegl-chant.h	Sun Jun 15 22:41:20 2008
@@ -38,6 +38,10 @@
 static void gegl_chant_class_intern_init   (gpointer     klass);
 static gpointer chant_parent_class = NULL;
 
+#ifdef SIMD_COMPILE
+#define GEGL_DEFINE_DYNAMIC_OPERATION(T_P)  
+#else
+
 #define GEGL_DEFINE_DYNAMIC_OPERATION(T_P)  GEGL_DEFINE_DYNAMIC_OPERATION_EXTENDED (GEGL_CHANT_C_FILE, GeglChant, gegl_chant, T_P, 0, {})
 #define GEGL_DEFINE_DYNAMIC_OPERATION_EXTENDED(C_FILE, TypeName, type_name, TYPE_PARENT, flags, CODE) \
 static void     type_name##_init              (TypeName        *self);  \
@@ -89,6 +93,7 @@
     g_define_type_id = type_name##_type_id;                             \
     { CODE ; }                                                          \
   }
+#endif
 
 
 #define GEGL_CHANT_PROPERTIES(op) \
@@ -288,6 +293,63 @@
   GEGL_MODULE_ABI_VERSION
 };
 
+#if (defined SIMD_COMPILE) | (defined SIMD_MASTER)
+
+void simd_add_default (GObjectClass *klass);
+void simd_add_sse (GObjectClass *klass);
+void simd_add_mmx (GObjectClass *klass);
+
+#endif
+
+#ifdef SIMD_COMPILE
+
+/* the following is just to consume defined functions to quieten gcc for
+ * the simd compiles, where some of the static functions are left unused.
+ */
+void gegl_chant_register_type (GTypeModule *module) { };
+static void bar(void);
+static void gegl_chant_class_init (GeglChantClass *klass);
+static void foo(void) {
+  gegl_chant_init (NULL);
+  gegl_chant_class_init (NULL);
+  gegl_chant_class_finalize (NULL);
+  gegl_chant_class_intern_init (NULL);
+  gegl_chant_register_type (NULL);
+  bar();
+}
+static void bar(void) {
+  foo();
+}
+
+#ifdef SIMD_DEFAULT
+#define GEGL_SIMD(callback) \
+void simd_add_default (GObjectClass *klass) { \
+    gegl_operation_class_add_processor (GEGL_OPERATION_CLASS (klass), G_CALLBACK (process_simd), "simd");\
+  }
+#else
+
+#ifdef SIMD_SSE
+#define GEGL_SIMD(callback) \
+void simd_add_sse (GObjectClass *klass) { \
+    gegl_operation_class_add_processor (GEGL_OPERATION_CLASS (klass), G_CALLBACK (process_simd), "simd");\
+  }
+#else
+
+#ifdef SIMD_MMX
+#define GEGL_SIMD(callback) \
+void simd_add_mmx (GObjectClass *klass) { \
+    gegl_operation_class_add_processor (GEGL_OPERATION_CLASS (klass), G_CALLBACK (process_simd), "simd");\
+  }
+#else
+
+#error capable simd not included in gegl-chant
+
+#endif
+
+#endif
+#endif
+
+#else
 /* prototypes added to silence warnings from gcc for -Wmissing-prototypes*/
 gboolean                gegl_module_register (GTypeModule *module);
 const GeglModuleInfo  * gegl_module_query    (GTypeModule *module);
@@ -307,6 +369,8 @@
 }
 #endif
 
+#endif
+
 
 struct _GeglChantO
 {
@@ -742,6 +806,27 @@
 #undef gegl_chant_color
 #undef gegl_chant_curve
 #undef gegl_chant_vector
+
+
+#ifdef SIMD_MASTER
+  {
+    GeglCpuAccelFlags flags = gegl_cpu_accel_get_support ();
+
+    if (flags & GEGL_CPU_ACCEL_X86_SSE &&
+        flags & GEGL_CPU_ACCEL_X86_MMX)
+      {
+        simd_add_sse (klass);
+      }
+    else if (flags & GEGL_CPU_ACCEL_X86_MMX)
+      {
+        simd_add_mmx (klass);
+      }
+    else
+      {
+        simd_add_default (klass);
+      }
+  }
+#endif
 }
 
 

Modified: trunk/gegl/gegl-plugin.h
==============================================================================
--- trunk/gegl/gegl-plugin.h	(original)
+++ trunk/gegl/gegl-plugin.h	Sun Jun 15 22:41:20 2008
@@ -35,6 +35,7 @@
 typedef struct _GeglConnection       GeglConnection;
 
 #include <gegl-utils.h>
+#include <gegl-cpuaccel.h>
 #include <gegl-buffer.h>
 #include <gegl-paramspecs.h>
 #include <gmodule.h>

Modified: trunk/operations/Makefile-operations.am
==============================================================================
--- trunk/operations/Makefile-operations.am	(original)
+++ trunk/operations/Makefile-operations.am	Sun Jun 15 22:41:20 2008
@@ -10,10 +10,29 @@
 
 all-local: $(plugins)
 
+if USE_SSE
+
+%.la: %.c $(GEGLHEADERS)
+	grep GEGL_SIMD $< && (\
+        $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $  lo $< \
+            -DSIMD_MASTER && \
+        $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $ -simd lo $< \
+            -DSIMD_COMPILE -DSIMD_DEFAULT &&\
+        $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(MMX_EXTRA_CFLAGS) -c -o $ -mmx lo $< \
+            -DSIMD_COMPILE -DSIMD_MMX &&\
+        $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(SSE_EXTRA_CFLAGS) -c -o $ -sse lo $< \
+            -DSIMD_COMPILE -DSIMD_SSE &&\
+        $(LIBTOOL) --tag=CC --mode=link $(CC) $(AM_LDFLAGS) $(LDFLAGS) $(CFLAGS) $(LDADD) -o $@ -rpath $(ext_dir) $ -sse lo $ -mmx lo $ -simd lo $  lo ) || (\
+        $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $  lo $< &&\
+        $(LIBTOOL) --tag=CC --mode=link $(CC) $(AM_LDFLAGS) $(LDFLAGS) $(CFLAGS) $(LDADD) -o $@ -rpath $(ext_dir) $  lo )
+
+else
+
 %.la: %.c $(GEGLHEADERS)
 	$(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $  lo $<
 	$(LIBTOOL) --tag=CC --mode=link $(CC) $(AM_LDFLAGS) $(LDFLAGS) $(CFLAGS) $(LDADD) -o $@ -rpath $(ext_dir) $  lo
 
+endif
 
 clean-local:
 	rm -f *.la $(OFILES)

Modified: trunk/operations/common/brightness-contrast.c
==============================================================================
--- trunk/operations/common/brightness-contrast.c	(original)
+++ trunk/operations/common/brightness-contrast.c	Sun Jun 15 22:41:20 2008
@@ -109,40 +109,6 @@
 }
 
 
-#ifdef HAS_G4FLOAT
-/* The compiler supports vector extensions allowing an version of
- * the process code that produces more optimal instructions on the
- * target platform.
- */
-
-static gboolean
-process_simd (GeglOperation       *op,
-              void                *in_buf,
-              void                *out_buf,
-              glong                samples,
-              const GeglRectangle *roi)
-{
-  GeglChantO *o   = GEGL_CHANT_PROPERTIES (op);
-  g4float    *in  = in_buf;
-  g4float    *out = out_buf;
-
-  /* add 0.5 to brightness here to make the logic in the innerloop tighter
-   */
-  g4float  brightness = g4float_all(o->brightness + 0.5);
-  g4float  contrast   = g4float_all(o->contrast);
-  g4float  half       = g4float_half;
-
-  while (samples--)
-    {
-      *out = (*in - half) * contrast + brightness;
-      g4floatA(*out)=g4floatA(*in);
-      in  ++;
-      out ++;
-    }
-  return TRUE;
-}
-#endif
-
 /*
  * The class init function sets up information needed for this operations class
  * (template) in the GObject OO framework.
@@ -173,16 +139,44 @@
 
   /* a description of what this operations does */
   operation_class->description = _("Changes the light level and contrast.");
+}
 
 
-#ifdef HAS_G4FLOAT
-  /* add conditionally compiled variation of process(), gegl should be able
-   * to determine which is fastest and hopefully if any implementation is
-   * broken and not conforming to the reference implementation.
+#ifdef GEGL_SIMD
+/* The following is turned into MMX and SSE code by gcc, that gets
+ * used at runtime if the cpu supports it.
+ */
+static gboolean
+process_simd (GeglOperation       *op,
+              void                *in_buf,
+              void                *out_buf,
+              glong                samples,
+              const GeglRectangle *roi)
+{
+  GeglChantO *o   = GEGL_CHANT_PROPERTIES (op);
+  g4float    *in  = in_buf;
+  g4float    *out = out_buf;
+
+  /* add 0.5 to brightness here to make the logic in the innerloop tighter
    */
-  gegl_operation_class_add_processor (operation_class,
-                                      G_CALLBACK (process_simd), "simd");
-#endif
+  g4float  brightness = g4float_all(o->brightness + 0.5);
+  g4float  contrast   = g4float_all(o->contrast);
+  g4float  half       = g4float_half;
+
+  while (samples--)
+    {
+      *out = (*in - half) * contrast + brightness;
+      g4floatA(*out)=g4floatA(*in);
+      in  ++;
+      out ++;
+    }
+  return TRUE;
 }
+/* the GEGL_SIMD macro needs to be used on the SIMD code using process,
+   this causes the correct version to be registered as a fast path for
+   GeglOperaiton at runtime
+*/
+GEGL_SIMD (process_simd)
+#endif
 
 #endif /* closing #ifdef GEGL_CHANT_PROPERTIES ... else ... */

Modified: trunk/operations/common/invert.c
==============================================================================
--- trunk/operations/common/invert.c	(original)
+++ trunk/operations/common/invert.c	Sun Jun 15 22:41:20 2008
@@ -23,7 +23,6 @@
 
 #define GEGL_CHANT_TYPE_POINT_FILTER
 #define GEGL_CHANT_C_FILE       "invert.c"
-#define GEGLV4
 
 #include "gegl-chant.h"
 
@@ -55,7 +54,27 @@
   return TRUE;
 }
 
-#ifdef HAS_G4FLOAT
+
+static void
+gegl_chant_class_init (GeglChantClass *klass)
+{
+  GeglOperationClass            *operation_class;
+  GeglOperationPointFilterClass *point_filter_class;
+
+  operation_class    = GEGL_OPERATION_CLASS (klass);
+  point_filter_class = GEGL_OPERATION_POINT_FILTER_CLASS (klass);
+
+  point_filter_class->process = process;
+
+  operation_class->name        = "invert";
+  operation_class->categories  = "color";
+  operation_class->description =
+     "Inverts the components (except alpha), the result is the"
+     " corresponding \"negative\" image.";
+}
+
+
+#ifdef GEGL_SIMD
 static gboolean
 process_simd (GeglOperation       *op,
               void                *in_buf,
@@ -77,29 +96,7 @@
     }
   return TRUE;
 }
+GEGL_SIMD(process_simd)
 #endif
 
-static void
-gegl_chant_class_init (GeglChantClass *klass)
-{
-  GeglOperationClass            *operation_class;
-  GeglOperationPointFilterClass *point_filter_class;
-
-  operation_class    = GEGL_OPERATION_CLASS (klass);
-  point_filter_class = GEGL_OPERATION_POINT_FILTER_CLASS (klass);
-
-  point_filter_class->process = process;
-
-  operation_class->name        = "invert";
-  operation_class->categories  = "color";
-  operation_class->description =
-     "Inverts the components (except alpha), the result is the"
-     " corresponding \"negative\" image.";
-
-#ifdef HAS_G4FLOAT
-  gegl_operation_class_add_processor (operation_class,
-                                      G_CALLBACK (process_simd), "simd");
-#endif
-}
-
 #endif

Modified: trunk/operations/generated/other-blend.rb
==============================================================================
--- trunk/operations/generated/other-blend.rb	(original)
+++ trunk/operations/generated/other-blend.rb	Sun Jun 15 22:41:20 2008
@@ -90,12 +90,6 @@
 
   point_composer_class->process = process;
   operation_class->prepare = prepare;
-
-#ifdef HAS_G4FLOAT
-  gegl_operation_class_add_processor (operation_class,
-                                      G_CALLBACK (process_gegl4float), "simd");
-#endif
-
 '
 
 file_tail2 = '  operation_class->categories  = "compositors:porter-duff";
@@ -155,15 +149,15 @@
   return TRUE;
 }
 
-#ifdef HAS_G4FLOAT
+#ifdef GEGL_SIMD
 
 static gboolean
-process_gegl4float (GeglOperation      *op,
-                    void               *in_buf,
-                    void                *aux_buf,
-                    void                *out_buf,
-                    glong                n_pixels,
-                    const GeglRectangle *roi)
+process_simd (GeglOperation      *op,
+              void               *in_buf,
+              void                *aux_buf,
+              void                *out_buf,
+              glong                n_pixels,
+              const GeglRectangle *roi)
 {
   g4float *A = aux_buf;
   g4float *B = in_buf;
@@ -181,6 +175,8 @@
 
   return TRUE;
 }
+GEGL_SIMD (process_simd);
+
 
 #endif
 

Modified: trunk/operations/generated/svg-12-porter-duff.rb
==============================================================================
--- trunk/operations/generated/svg-12-porter-duff.rb	(original)
+++ trunk/operations/generated/svg-12-porter-duff.rb	Sun Jun 15 22:41:20 2008
@@ -119,12 +119,6 @@
 
   point_composer_class->process = process;
   operation_class->prepare = prepare;
-
-#ifdef HAS_G4FLOAT
-  gegl_operation_class_add_processor (operation_class,
-                                      G_CALLBACK (process_simd), "simd");
-#endif
-
 '
 
 file_tail2 = '  operation_class->categories  = "compositors:porter-duff";
@@ -184,7 +178,7 @@
   return TRUE;
 }
 
-#ifdef HAS_G4FLOAT
+#ifdef GEGL_SIMD
 
 static gboolean
 process_simd (GeglOperation       *op,
@@ -210,6 +204,7 @@
 
   return TRUE;
 }
+GEGL_SIMD(process_simd)
 
 #endif
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]