[gegl] Major refactoring in point-filter-cl



commit df54426d257c62ffe9307636839cb420031938c5
Author: Victor Oliveira <victormatheus gmail com>
Date:   Sun Jan 8 15:39:32 2012 -0200

    Major refactoring in point-filter-cl
    
    GeglBufferClIterator created and using it in point-filter-cl

 gegl/buffer/Makefile.am                      |    2 +
 gegl/buffer/gegl-buffer-cl-iterator.c        |  389 ++++++++++++++++++++++++++
 gegl/buffer/gegl-buffer-cl-iterator.h        |   36 +++
 gegl/buffer/gegl-buffer-private.h            |    1 +
 gegl/opencl/gegl-cl-texture-manager.c        |    4 +-
 gegl/operation/gegl-operation-point-filter.c |  210 ++-------------
 6 files changed, 449 insertions(+), 193 deletions(-)
---
diff --git a/gegl/buffer/Makefile.am b/gegl/buffer/Makefile.am
index 47189ad..10f9628 100644
--- a/gegl/buffer/Makefile.am
+++ b/gegl/buffer/Makefile.am
@@ -20,6 +20,7 @@ libbuffer_la_SOURCES = \
     gegl-buffer-share.c		\
     gegl-buffer-index.h		\
     gegl-buffer-iterator.c	\
+    gegl-buffer-cl-iterator.c	\
     gegl-buffer-linear.c	\
     gegl-buffer-save.c		\
     gegl-buffer-load.c		\
@@ -48,6 +49,7 @@ libbuffer_la_SOURCES = \
     gegl-buffer.h		\
     gegl-buffer-private.h	\
     gegl-buffer-iterator.h	\
+    gegl-buffer-cl-iterator.h	\
     gegl-buffer-load.h		\
     gegl-buffer-save.h		\
     gegl-buffer-types.h		\
diff --git a/gegl/buffer/gegl-buffer-cl-iterator.c b/gegl/buffer/gegl-buffer-cl-iterator.c
new file mode 100644
index 0000000..4a2d588
--- /dev/null
+++ b/gegl/buffer/gegl-buffer-cl-iterator.c
@@ -0,0 +1,389 @@
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <glib-object.h>
+#include <glib/gprintf.h>
+
+#include "gegl.h"
+
+#include "gegl-buffer-types.h"
+#include "gegl-buffer-cl-iterator.h"
+#include "gegl-buffer-private.h"
+#include "gegl-tile-storage.h"
+#include "gegl-utils.h"
+
+#define CL_ERROR {g_printf("[OpenCL] Error in %s:%d %s - %s\n", __FILE__, __LINE__, __func__, gegl_cl_errstring(errcode)); g_assert(FALSE);}
+
+typedef struct GeglBufferClIterators
+{
+  /* current region of interest */
+  gint          n;
+  size_t        size [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX][2];  /* length of current data in pixels */
+  cl_mem        tex  [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
+  GeglRectangle roi  [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
+
+  /* the following is private: */
+  cl_mem        tex_aux [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
+
+  gint           iterators;
+  gint           iteration_no;
+  gboolean       is_finished;
+
+  guint          flags          [GEGL_CL_BUFFER_MAX_ITERATORS];
+
+  GeglRectangle  rect           [GEGL_CL_BUFFER_MAX_ITERATORS]; /* the region we iterate on. They can be
+                                                                   different from each other, but width
+                                                                   and height are the same */
+
+  const Babl    *format         [GEGL_CL_BUFFER_MAX_ITERATORS]; /* The format required for the data */
+  GeglBuffer    *buffer         [GEGL_CL_BUFFER_MAX_ITERATORS];
+
+  /* buffer->format */
+  cl_image_format buf_cl_format [GEGL_CL_BUFFER_MAX_ITERATORS];
+  /* format */
+  cl_image_format op_cl_format  [GEGL_CL_BUFFER_MAX_ITERATORS];
+
+  gegl_cl_color_op conv         [GEGL_CL_BUFFER_MAX_ITERATORS];
+
+  /* total iteration */
+  gint           rois;
+  gint           roi_no;
+  GeglRectangle *roi_all;
+
+} GeglBufferClIterators;
+
+gint
+gegl_buffer_cl_iterator_add (GeglBufferClIterator  *iterator,
+                             GeglBuffer            *buffer,
+                             const GeglRectangle   *result,
+                             const Babl            *format,
+                             guint                  flags)
+{
+  GeglBufferClIterators *i = (gpointer)iterator;
+  gint self = 0;
+  if (i->iterators+1 > GEGL_CL_BUFFER_MAX_ITERATORS)
+    {
+      g_error ("too many iterators (%i)", i->iterators+1);
+    }
+
+  if (i->iterators == 0) /* for sanity, we zero at init */
+    {
+      memset (i, 0, sizeof (GeglBufferClIterators));
+    }
+
+  self = i->iterators++;
+
+  if (!result)
+    result = self==0?&(buffer->extent):&(i->rect[0]);
+  i->rect[self]=*result;
+
+  i->buffer[self]= g_object_ref (buffer);
+
+  if (format)
+    i->format[self]=format;
+  else
+    i->format[self]=buffer->format;
+  i->flags[self]=flags;
+
+  if (flags == GEGL_CL_BUFFER_WRITE)
+    i->conv[self] = gegl_cl_color_supported (format, buffer->format);
+  else
+    i->conv[self] = gegl_cl_color_supported (buffer->format, format);
+
+  gegl_cl_color_babl (buffer->format, &i->buf_cl_format[self], NULL);
+  gegl_cl_color_babl (format,         &i->op_cl_format [self], NULL);
+
+  if (self!=0)
+    {
+      /* we make all subsequently added iterators share the width and height of the first one */
+      i->rect[self].width  = i->rect[0].width;
+      i->rect[self].height = i->rect[0].height;
+    }
+  else
+    {
+      gint x, y, j;
+
+      i->rois = 0;
+      for (y=result->y; y < result->y + result->height; y += cl_state.max_image_height)
+        for (x=result->x; x < result->x + result->width;  x += cl_state.max_image_width)
+          i->rois++;
+
+      i->roi_no = 0;
+      i->roi_all = g_new0 (GeglRectangle, i->rois);
+
+      j = 0;
+      for (y=0; y < result->height; y += cl_state.max_image_height)
+        for (x=0; x < result->width;  x += cl_state.max_image_width)
+          {
+            GeglRectangle r = {x, y,
+                               MIN(cl_state.max_image_width,  result->width  - x),
+                               MIN(cl_state.max_image_height, result->height - y)};
+            i->roi_all[j] = r;
+            j++;
+          }
+    }
+
+  return self;
+}
+
+gboolean
+gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator)
+{
+  GeglBufferClIterators *i = (gpointer)iterator;
+  gboolean result = FALSE;
+  gint no;
+
+  const size_t origin_zero[3] = {0, 0, 0};
+
+  if (i->is_finished)
+    g_error ("%s called on finished buffer iterator", G_STRFUNC);
+  if (i->iteration_no == 0)
+    {
+      for (no=0; no<i->iterators;no++)
+        {
+          gint j;
+          gboolean found = FALSE;
+          for (j=0; j<no; j++)
+            if (i->buffer[no]==i->buffer[j])
+              {
+                found = TRUE;
+                break;
+              }
+          if (!found)
+            gegl_buffer_lock (i->buffer[no]);
+        }
+    }
+  else
+    {
+      gint j;
+      cl_int errcode = 0;
+
+      /* complete pending write work */
+      for (no=0; no<i->iterators;no++)
+        {
+          if (i->flags[no] == GEGL_CL_BUFFER_WRITE)
+            {
+              /* Wait Processing */
+              errcode = gegl_clEnqueueBarrier(gegl_cl_get_command_queue());
+              if (errcode != CL_SUCCESS) CL_ERROR;
+
+              /* color conversion in the GPU (output) */
+              if (i->conv[no] == CL_COLOR_CONVERT)
+                for (j=0; j < i->n; j++)
+                  {
+                    g_assert (i->tex_aux[no][j] == NULL);
+                    i->tex_aux[no][j] = gegl_clCreateImage2D (gegl_cl_get_context (),
+                                                              CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE,
+                                                              &i->buf_cl_format[no],
+                                                              i->roi[no][j].width,
+                                                              i->roi[no][j].height,
+                                                              0, NULL, &errcode);
+                    if (errcode != CL_SUCCESS) CL_ERROR;
+
+                    errcode = gegl_cl_color_conv (&i->tex[no][j], &i->tex_aux[no][j], i->size[no][j],
+                                                  i->format[no], i->buffer[no]->format);
+                    if (errcode != CL_SUCCESS) CL_ERROR;
+                  }
+
+              /* Wait Processing */
+              errcode = gegl_clEnqueueBarrier(gegl_cl_get_command_queue());
+              if (errcode != CL_SUCCESS) CL_ERROR;
+
+              /* GPU -> CPU */
+              for (j=0; j < i->n; j++)
+                {
+                  gpointer data;
+                  size_t pitch;
+                  const size_t region[3] = {i->roi[no][j].width, i->roi[no][j].height, 1};
+
+                  data = gegl_clEnqueueMapImage(gegl_cl_get_command_queue(), i->tex[no][j], CL_TRUE,
+                                                CL_MAP_READ,
+                                                origin_zero, region, &pitch, NULL,
+                                                0, NULL, NULL, &errcode);
+                  if (errcode != CL_SUCCESS) CL_ERROR;
+
+                  /* tile-ize */
+                  if (i->conv[no] == CL_COLOR_NOT_SUPPORTED)
+                    /* color conversion using BABL */
+                    gegl_buffer_set (i->buffer[no], &i->roi[no][j], i->format[no], data, pitch);
+                  else
+                    /* color conversion has already been performed in the GPU */
+                    gegl_buffer_set (i->buffer[no], &i->roi[no][j], i->buffer[no]->format, data, pitch);
+
+                  errcode = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex[no][j], data,
+                                                          0, NULL, NULL);
+                  if (errcode != CL_SUCCESS) CL_ERROR;
+                }
+            }
+        }
+
+      /* Run! */
+      errcode = gegl_clFinish(gegl_cl_get_command_queue());
+      if (errcode != CL_SUCCESS) CL_ERROR;
+
+      for (no=0; no < i->iterators; no++)
+        for (j=0; j < i->n; j++)
+          {
+            if (i->tex_aux[no][j]) gegl_clReleaseMemObject (i->tex_aux[no][j]);
+            gegl_clReleaseMemObject (i->tex[no][j]);
+
+            i->tex_aux[no][j] = NULL;
+            i->tex[no][j] = NULL;
+          }
+    }
+
+  g_assert (i->iterators > 0);
+  result = (i->roi_no >= i->rois)? FALSE : TRUE;
+
+  i->n = MIN(GEGL_CL_NTEX, i->rois - i->roi_no);
+
+  /* then we iterate all */
+  for (no=0; no<i->iterators;no++)
+    {
+      int j;
+      int errcode = 0;
+
+      for (j = 0; j < i->n; j++)
+        {
+          GeglRectangle r = {i->rect[no].x + i->roi_all[i->roi_no+j].x,
+                             i->rect[no].y + i->roi_all[i->roi_no+j].y,
+                             i->roi_all[i->roi_no+j].width,
+                             i->roi_all[i->roi_no+j].height};
+          i->roi [no][j] = r;
+
+          i->size[no][j][0] = r.width;
+          i->size[no][j][1] = r.height;
+        }
+
+      if (i->flags[no] == GEGL_CL_BUFFER_READ)
+        {
+          for (j=0; j < i->n; j++)
+            {
+              gpointer data;
+              size_t pitch;
+              const size_t region[3] = {i->roi[no][j].width, i->roi[no][j].height, 1};
+
+              g_assert (i->tex[no][j] == NULL);
+              i->tex[no][j] = gegl_clCreateImage2D (gegl_cl_get_context (),
+                                                    CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE,
+                                                    (i->conv[no] == CL_COLOR_CONVERT)?
+                                                      &i->buf_cl_format[no] :
+                                                      &i->op_cl_format [no],
+                                                    i->roi[no][j].width,
+                                                    i->roi[no][j].height,
+                                                    0, NULL, &errcode);
+              if (errcode != CL_SUCCESS) CL_ERROR;
+
+              /* pre-pinned memory */
+              data = gegl_clEnqueueMapImage(gegl_cl_get_command_queue(), i->tex[no][j], CL_TRUE,
+                                            CL_MAP_WRITE,
+                                            origin_zero, region, &pitch, NULL,
+                                            0, NULL, NULL, &errcode);
+              if (errcode != CL_SUCCESS) CL_ERROR;
+
+              /* un-tile */
+              if (i->conv[no] == CL_COLOR_NOT_SUPPORTED)
+                /* color conversion using BABL */
+                gegl_buffer_get (i->buffer[no], 1.0, &i->roi[no][j], i->format[no], data, pitch);
+              else
+                /* color conversion will be performed in the GPU later */
+                gegl_buffer_get (i->buffer[no], 1.0, &i->roi[no][j], i->buffer[no]->format, data, pitch);
+
+              errcode = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex[no][j], data,
+                                                      0, NULL, NULL);
+              if (errcode != CL_SUCCESS) CL_ERROR;
+            }
+
+          errcode = gegl_clEnqueueBarrier(gegl_cl_get_command_queue());
+          if (errcode != CL_SUCCESS) CL_ERROR;
+
+          /* color conversion in the GPU (input) */
+          if (i->conv[no] == CL_COLOR_CONVERT)
+            for (j = 0; j < i->n; j++)
+              {
+                g_assert (i->tex_aux[no][j] == NULL);
+
+                i->tex_aux[no][j] = gegl_clCreateImage2D (gegl_cl_get_context (),
+                                                          CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE,
+                                                          &i->op_cl_format[no],
+                                                          i->roi[no][j].width,
+                                                          i->roi[no][j].height,
+                                                          0, NULL, &errcode);
+                if (errcode != CL_SUCCESS) CL_ERROR;
+
+                errcode = gegl_cl_color_conv (&i->tex[no][j], &i->tex_aux[no][j], i->size[no][j],
+                                              i->buffer[no]->format, i->format[no]);
+                if (errcode == FALSE) CL_ERROR;
+              }
+        }
+      else if (i->flags[no] == GEGL_CL_BUFFER_WRITE)
+        {
+          for (j=0; j < i->n; j++)
+            {
+              g_assert (i->tex[no][j] == NULL);
+
+              i->tex[no][j] = gegl_clCreateImage2D (gegl_cl_get_context (),
+                                                    CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE,
+                                                    &i->op_cl_format [no],
+                                                    i->roi[no][j].width,
+                                                    i->roi[no][j].height,
+                                                    0, NULL, &errcode);
+              if (errcode != CL_SUCCESS) CL_ERROR;
+            }
+        }
+      else
+        {
+          g_assert (FALSE);
+        }
+    }
+
+  i->roi_no += i->n;
+
+  i->iteration_no++;
+
+  if (result == FALSE)
+    {
+      for (no=0; no<i->iterators;no++)
+        {
+          gint j;
+          gboolean found = FALSE;
+          for (j=0; j<no; j++)
+            if (i->buffer[no]==i->buffer[j])
+              {
+                found = TRUE;
+                break;
+              }
+          if (!found)
+            gegl_buffer_unlock (i->buffer[no]);
+        }
+
+      for (no=0; no<i->iterators;no++)
+        {
+          g_object_unref (i->buffer[no]);
+        }
+
+      i->is_finished = TRUE;
+
+      g_free (i->roi_all);
+      g_slice_free (GeglBufferClIterators, i);
+    }
+
+  return result;
+}
+
+GeglBufferClIterator *
+gegl_buffer_cl_iterator_new (GeglBuffer          *buffer,
+                             const GeglRectangle *roi,
+                             const Babl          *format,
+                             guint                flags)
+{
+  GeglBufferClIterator *i = (gpointer)g_slice_new0 (GeglBufferClIterators);
+  /* Because the iterator is nulled above, we can forgo explicitly setting
+   * i->is_finished to FALSE. */
+  gegl_buffer_cl_iterator_add (i, buffer, roi, format, flags);
+  return i;
+}
+
+#undef CL_ERROR
diff --git a/gegl/buffer/gegl-buffer-cl-iterator.h b/gegl/buffer/gegl-buffer-cl-iterator.h
new file mode 100644
index 0000000..6bba2a6
--- /dev/null
+++ b/gegl/buffer/gegl-buffer-cl-iterator.h
@@ -0,0 +1,36 @@
+#ifndef __GEGL_BUFFER_CL_ITERATOR_H__
+#define __GEGL_BUFFER_CL_ITERATOR_H__
+
+#include "gegl-buffer.h"
+#include "opencl/gegl-cl.h"
+
+#define GEGL_CL_NTEX 16
+#define GEGL_CL_BUFFER_MAX_ITERATORS 6
+
+enum
+{
+  GEGL_CL_BUFFER_READ   = 1,
+  GEGL_CL_BUFFER_WRITE  = 2
+};
+
+typedef struct GeglBufferClIterator
+{
+  gint          n;
+  size_t        size [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX][2];  /* length of current data in pixels */
+  cl_mem        tex  [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
+  GeglRectangle roi  [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
+} GeglBufferClIterator;
+
+gint gegl_buffer_cl_iterator_add (GeglBufferClIterator  *iterator,
+                                  GeglBuffer            *buffer,
+                                  const GeglRectangle   *roi,
+                                  const Babl            *format,
+                                  guint                  flags);
+
+gboolean gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator);
+
+GeglBufferClIterator *gegl_buffer_cl_iterator_new (GeglBuffer          *buffer,
+                                                   const GeglRectangle *roi,
+                                                   const Babl          *format,
+                                                   guint                flags);
+#endif
diff --git a/gegl/buffer/gegl-buffer-private.h b/gegl/buffer/gegl-buffer-private.h
index d4712d1..9cf188f 100644
--- a/gegl/buffer/gegl-buffer-private.h
+++ b/gegl/buffer/gegl-buffer-private.h
@@ -24,6 +24,7 @@
 #include "gegl-buffer.h"
 #include "gegl-tile-handler.h"
 #include "gegl-buffer-iterator.h"
+#include "gegl-buffer-cl-iterator.h"
 
 #define GEGL_BUFFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GEGL_TYPE_BUFFER, GeglBufferClass))
 #define GEGL_IS_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GEGL_TYPE_BUFFER))
diff --git a/gegl/opencl/gegl-cl-texture-manager.c b/gegl/opencl/gegl-cl-texture-manager.c
index 312adb5..2340aa4 100644
--- a/gegl/opencl/gegl-cl-texture-manager.c
+++ b/gegl/opencl/gegl-cl-texture-manager.c
@@ -30,10 +30,10 @@ gegl_cl_texture_manager_request (cl_mem_flags flags,
   for (i=0; i<tex_pool->len; i++)
     {
       TextureInfo *info = &g_array_index (tex_pool, TextureInfo, i);
-      if (info->flags == flags &&
+      if ((flags & info->flags) &&
           info->format.image_channel_order     == format.image_channel_order     &&
           info->format.image_channel_data_type == format.image_channel_data_type &&
-          info->width >= width && info->height >= height &&
+          info->width == width && info->height == height &&
           info->used == 0)
         {
           info->used ++;
diff --git a/gegl/operation/gegl-operation-point-filter.c b/gegl/operation/gegl-operation-point-filter.c
index b1a59da..746ee31 100644
--- a/gegl/operation/gegl-operation-point-filter.c
+++ b/gegl/operation/gegl-operation-point-filter.c
@@ -33,7 +33,6 @@
 #include "gegl-tile-storage.h"
 
 #include "opencl/gegl-cl.h"
-#include "opencl/gegl-cl-texture-manager.h"
 
 static gboolean gegl_operation_point_filter_process
                               (GeglOperation       *operation,
@@ -73,45 +72,22 @@ gegl_operation_point_filter_init (GeglOperationPointFilter *self)
 {
 }
 
-struct buf_tex
-{
-  GeglBuffer *buf;
-  GeglRectangle *region;
-  cl_mem *tex;
-};
-
 //#define CL_ERROR {g_assert(0);}
 #define CL_ERROR {g_printf("[OpenCL] Error in %s:%d %s - %s\n", __FILE__, __LINE__, __func__, gegl_cl_errstring(errcode)); goto error;}
 
 static gboolean
-gegl_operation_point_filter_cl_process_full (GeglOperation       *operation,
-                                             GeglBuffer          *input,
-                                             GeglBuffer          *output,
-                                             const GeglRectangle *result)
+gegl_operation_point_filter_cl_process (GeglOperation       *operation,
+                                        GeglBuffer          *input,
+                                        GeglBuffer          *output,
+                                        const GeglRectangle *result)
 {
   const Babl *in_format  = gegl_operation_get_format (operation, "input");
   const Babl *out_format = gegl_operation_get_format (operation, "output");
 
   GeglOperationPointFilterClass *point_filter_class = GEGL_OPERATION_POINT_FILTER_GET_CLASS (operation);
 
-  int y, x, i;
-  int errcode = 0;
-
-  gfloat** out_data = NULL;
-
-  int ntex = 0;
-  struct buf_tex input_tex;
-  struct buf_tex output_tex;
-
-  const size_t origin_zero[3] = {0, 0, 0};
-
-  gegl_cl_color_op conv_in;
-  gegl_cl_color_op conv_out;
-
-  cl_image_format in_image_format;
-  cl_image_format out_image_format;
-
-  size_t bpp;
+  gint j;
+  cl_int errcode = 0;
 
   /* non-texturizable format! */
   if (!gegl_cl_color_babl (in_format,  NULL, NULL) ||
@@ -121,178 +97,30 @@ gegl_operation_point_filter_cl_process_full (GeglOperation       *operation,
       return FALSE;
     }
 
-  if (!gegl_cl_color_babl (input->format, &in_image_format, &bpp))
-    gegl_cl_color_babl (in_format, &in_image_format, &bpp);
-
-  if (!gegl_cl_color_babl (output->format, &out_image_format, &bpp))
-    gegl_cl_color_babl (out_format, &out_image_format, &bpp);
-
-  conv_in  = gegl_cl_color_supported (input->format,   in_format);
-  conv_out = gegl_cl_color_supported (out_format, output->format);
-
-  g_printf("[OpenCL] BABL formats: (%s,%s:%d) (%s,%s:%d)\n \t Tile Size:(%d, %d)\n",
+  g_printf("[OpenCL] BABL formats: (%s,%s) (%s,%s)\n \t Tile Size:(%d, %d)\n",
            babl_get_name(input->format),
            babl_get_name(in_format),
-           conv_in,
            babl_get_name(out_format),
            babl_get_name(output->format),
-           conv_out,
            input->tile_storage->tile_width,
            input->tile_storage->tile_height);
 
-  for (y=result->y; y < result->y + result->height; y += cl_state.max_image_height)
-   for (x=result->x; x < result->x + result->width;  x += cl_state.max_image_width)
-     ntex++;
-
-  input_tex.region  = (GeglRectangle *) g_new0 (GeglRectangle, ntex);
-  output_tex.region = (GeglRectangle *) g_new0 (GeglRectangle, ntex);
-  input_tex.tex     = (cl_mem *)        g_new0 (cl_mem,        ntex);
-  output_tex.tex    = (cl_mem *)        g_new0 (cl_mem,        ntex);
-
-  i = 0;
-  for (y=result->y; y < result->y + result->height; y += cl_state.max_image_height)
-    for (x=result->x; x < result->x + result->width;  x += cl_state.max_image_width)
-      {
-        const size_t region[3] = {MIN(cl_state.max_image_width,  result->x + result->width  - x),
-                                  MIN(cl_state.max_image_height, result->y + result->height - y),
-                                  1};
-
-        GeglRectangle r = {x, y, region[0], region[1]};
-        input_tex.region[i] = output_tex.region[i] = r;
-
-        input_tex.tex[i]  = gegl_cl_texture_manager_request (CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE,
-                                                             in_image_format,
-                                                             region[0], region[1]);
-        if (input_tex.tex[i]  == NULL) CL_ERROR;
-
-        output_tex.tex[i] = gegl_cl_texture_manager_request (CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE,
-                                                             out_image_format,
-                                                             region[0], region[1]);
-        if (output_tex.tex[i] == NULL) CL_ERROR;
-
-        i++;
-      }
-
-  for (i=0; i < ntex; i++)
-    {
-      gpointer data;
-      size_t pitch;
-      const size_t region[3] = {input_tex.region[i].width, input_tex.region[i].height, 1};
-
-      /* pre-pinned memory */
-      data = gegl_clEnqueueMapImage(gegl_cl_get_command_queue(), input_tex.tex[i], CL_TRUE,
-                                    CL_MAP_WRITE,
-                                    origin_zero, region, &pitch, NULL,
-                                    0, NULL, NULL, &errcode);
-      if (errcode != CL_SUCCESS) CL_ERROR;
-
-      /* un-tile */
-      if (conv_in == CL_COLOR_NOT_SUPPORTED)
-        /* color conversion using BABL */
-        gegl_buffer_get (input, 1.0, &input_tex.region[i], in_format, data, pitch);
-      else
-        /* color conversion will be performed in the GPU later */
-        gegl_buffer_get (input, 1.0, &input_tex.region[i], input->format, data, pitch);
-
-      errcode = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), input_tex.tex[i], data,
-                                              0, NULL, NULL);
-      if (errcode != CL_SUCCESS) CL_ERROR;
-    }
-
-  errcode = gegl_clEnqueueBarrier(gegl_cl_get_command_queue());
-  if (errcode != CL_SUCCESS) CL_ERROR;
-
-  /* color conversion in the GPU (input) */
-  if (conv_in == CL_COLOR_CONVERT)
-    for (i=0; i < ntex; i++)
-     {
-       const size_t size[2] = {input_tex.region[i].width, input_tex.region[i].height};
-       errcode = gegl_cl_color_conv (&input_tex.tex[i], &output_tex.tex[i], size, input->format, in_format);
-       if (errcode == FALSE) CL_ERROR;
-     }
-
   /* Process */
-  for (i=0; i < ntex; i++)
-    {
-      const size_t region[3] = {input_tex.region[i].width, input_tex.region[i].height, 1};
-      const size_t global_worksize[2] = {region[0], region[1]};
-
-      errcode = point_filter_class->cl_process(operation, input_tex.tex[i], output_tex.tex[i], global_worksize, &input_tex.region[i]);
-      if (errcode != CL_SUCCESS) CL_ERROR;
-    }
-
-  /* Wait Processing */
-  errcode = gegl_clEnqueueBarrier(gegl_cl_get_command_queue());
-  if (errcode != CL_SUCCESS) CL_ERROR;
-
-  /* color conversion in the GPU (output) */
-  if (conv_out == CL_COLOR_CONVERT)
-    for (i=0; i < ntex; i++)
-     {
-       const size_t size[2] = {output_tex.region[i].width, output_tex.region[i].height};
-       errcode = gegl_cl_color_conv (&output_tex.tex[i], &input_tex.tex[i], size, out_format, output->format);
-     }
-
-  /* Wait Processing */
-  errcode = gegl_clEnqueueBarrier(gegl_cl_get_command_queue());
-  if (errcode != CL_SUCCESS) CL_ERROR;
-
-  /* GPU -> CPU */
-  for (i=0; i < ntex; i++)
-    {
-      gpointer data;
-      size_t pitch;
-      const size_t region[3] = {output_tex.region[i].width, output_tex.region[i].height, 1};
-
-      data = gegl_clEnqueueMapImage(gegl_cl_get_command_queue(), output_tex.tex[i], CL_TRUE,
-                                    CL_MAP_READ,
-                                    origin_zero, region, &pitch, NULL,
-                                    0, NULL, NULL, &errcode);
-      if (errcode != CL_SUCCESS) CL_ERROR;
-
-      /* tile-ize */
-      if (conv_out == CL_COLOR_NOT_SUPPORTED)
-        /* color conversion using BABL */
-        gegl_buffer_set (output, &output_tex.region[i], out_format, data, pitch);
-      else
-        /* color conversion has already been be performed in the GPU */
-        gegl_buffer_set (output, &output_tex.region[i], output->format, data, pitch);
-
-      errcode = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), output_tex.tex[i], data,
-                                              0, NULL, NULL);
-      if (errcode != CL_SUCCESS) CL_ERROR;
-    }
-
-  /* Run! */
-  errcode = gegl_clFinish(gegl_cl_get_command_queue());
-  if (errcode != CL_SUCCESS) CL_ERROR;
-
-  for (i=0; i < ntex; i++)
-    {
-      gegl_cl_texture_manager_give (input_tex.tex[i]);
-      gegl_cl_texture_manager_give (output_tex.tex[i]);
-    }
-
-  g_free(input_tex.tex);
-  g_free(output_tex.tex);
-  g_free(input_tex.region);
-  g_free(output_tex.region);
-
+  {
+    GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,   result, out_format, GEGL_CL_BUFFER_WRITE);
+                  gint read = gegl_buffer_cl_iterator_add (i, input, result, in_format,  GEGL_CL_BUFFER_READ);
+    while (gegl_buffer_cl_iterator_next (i))
+      for (j=0; j < i->n; j++)
+        {
+          errcode = point_filter_class->cl_process(operation, i->tex[read][j], i->tex[0][j],
+                                                   i->size[0][j], &i->roi[0][j]);
+          if (errcode != CL_SUCCESS) CL_ERROR;
+        }
+  }
   return TRUE;
 
 error:
 
-    for (i=0; i < ntex; i++)
-      {
-        if (input_tex.tex[i])  gegl_cl_texture_manager_give (input_tex.tex[i]);
-        if (output_tex.tex[i]) gegl_cl_texture_manager_give (output_tex.tex[i]);
-      }
-
-  if (input_tex.tex)     g_free(input_tex.tex);
-  if (output_tex.tex)    g_free(output_tex.tex);
-  if (input_tex.region)  g_free(input_tex.region);
-  if (output_tex.region) g_free(output_tex.region);
-
   return FALSE;
 }
 
@@ -314,7 +142,7 @@ gegl_operation_point_filter_process (GeglOperation       *operation,
     {
       if (cl_state.is_accelerated && point_filter_class->cl_process)
         {
-          if (gegl_operation_point_filter_cl_process_full (operation, input, output, result))
+          if (gegl_operation_point_filter_cl_process (operation, input, output, result))
             return TRUE;
         }
 



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