Blame gegl/buffer/gegl-buffer-cl-iterator.c

Packit bc1512
#include "config.h"
Packit bc1512
#include <stdlib.h>
Packit bc1512
#include <string.h>
Packit bc1512
#include <math.h>
Packit bc1512
Packit bc1512
#include <glib-object.h>
Packit bc1512
#include <glib/gprintf.h>
Packit bc1512
Packit bc1512
#include "gegl.h"
Packit bc1512
#include "gegl/gegl-debug.h"
Packit bc1512
Packit bc1512
#include "gegl-buffer-types.h"
Packit bc1512
#include "gegl-buffer-cl-iterator.h"
Packit bc1512
#include "gegl-buffer-cl-cache.h"
Packit bc1512
#include "gegl-buffer-private.h"
Packit bc1512
#include "gegl-tile-storage.h"
Packit bc1512
#include "gegl-utils.h"
Packit bc1512
Packit bc1512
#define CL_ERROR {GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error in %s:%d@%s - %s\n", __FILE__, __LINE__, __func__, gegl_cl_errstring(cl_err)); goto error;}
Packit bc1512
Packit bc1512
typedef struct GeglBufferClIterators
Packit bc1512
{
Packit bc1512
  /* current region of interest */
Packit bc1512
  gint          n;
Packit bc1512
  size_t        size [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];  /* length of current data in pixels */
Packit bc1512
  cl_mem        tex  [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
Packit bc1512
  GeglRectangle roi  [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
Packit bc1512
Packit bc1512
  /* the following is private: */
Packit bc1512
  cl_mem        tex_buf [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
Packit bc1512
  cl_mem        tex_op  [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
Packit bc1512
Packit bc1512
  /* don't free textures loaded from cache */
Packit bc1512
  gboolean       tex_buf_from_cache [GEGL_CL_BUFFER_MAX_ITERATORS][GEGL_CL_NTEX];
Packit bc1512
Packit bc1512
  gint           iterators;
Packit bc1512
  gint           iteration_no;
Packit bc1512
  gboolean       is_finished;
Packit bc1512
Packit bc1512
  guint          flags          [GEGL_CL_BUFFER_MAX_ITERATORS];
Packit bc1512
  gint           area           [GEGL_CL_BUFFER_MAX_ITERATORS][4];
Packit bc1512
Packit bc1512
  GeglRectangle  rect           [GEGL_CL_BUFFER_MAX_ITERATORS]; /* the region we iterate on. They can be
Packit bc1512
                                                                   different from each other, but width
Packit bc1512
                                                                   and height are the same */
Packit bc1512
Packit bc1512
  const Babl    *format         [GEGL_CL_BUFFER_MAX_ITERATORS]; /* The format required for the data */
Packit bc1512
  GeglBuffer    *buffer         [GEGL_CL_BUFFER_MAX_ITERATORS];
Packit bc1512
Packit bc1512
  /* buffer->soft_format */
Packit bc1512
  size_t buf_cl_format_size     [GEGL_CL_BUFFER_MAX_ITERATORS];
Packit bc1512
  /* format */
Packit bc1512
  size_t op_cl_format_size      [GEGL_CL_BUFFER_MAX_ITERATORS];
Packit bc1512
Packit bc1512
  gegl_cl_color_op conv         [GEGL_CL_BUFFER_MAX_ITERATORS];
Packit bc1512
Packit bc1512
  /* total iteration */
Packit bc1512
  gint           rois;
Packit bc1512
  gint           roi_no;
Packit bc1512
  GeglRectangle *roi_all;
Packit bc1512
Packit bc1512
} GeglBufferClIterators;
Packit bc1512
Packit bc1512
gint
Packit bc1512
gegl_buffer_cl_iterator_add_2 (GeglBufferClIterator  *iterator,
Packit bc1512
                               GeglBuffer            *buffer,
Packit bc1512
                               const GeglRectangle   *result,
Packit bc1512
                               const Babl            *format,
Packit bc1512
                               guint                  flags,
Packit bc1512
                               gint                   left,
Packit bc1512
                               gint                   right,
Packit bc1512
                               gint                   top,
Packit bc1512
                               gint                   bottom,
Packit bc1512
                               GeglAbyssPolicy        abyss_policy)
Packit bc1512
{
Packit bc1512
  GeglBufferClIterators *i = (gpointer)iterator;
Packit bc1512
  gint self = 0;
Packit bc1512
  if (i->iterators+1 > GEGL_CL_BUFFER_MAX_ITERATORS)
Packit bc1512
    {
Packit bc1512
      g_error ("too many iterators (%i)", i->iterators+1);
Packit bc1512
    }
Packit bc1512
Packit bc1512
  if (i->iterators == 0) /* for sanity, we zero at init */
Packit bc1512
    {
Packit bc1512
      memset (i, 0, sizeof (GeglBufferClIterators));
Packit bc1512
    }
Packit bc1512
Packit bc1512
  self = i->iterators++;
Packit bc1512
Packit bc1512
  if (!result)
Packit bc1512
    result = self==0?&(buffer->extent):&(i->rect[0]);
Packit bc1512
  i->rect[self]=*result;
Packit bc1512
Packit bc1512
  i->flags[self]=flags;
Packit bc1512
Packit bc1512
  if (flags == GEGL_CL_BUFFER_WRITE || flags == GEGL_CL_BUFFER_READ)
Packit bc1512
    {
Packit bc1512
      g_assert (buffer);
Packit bc1512
Packit bc1512
      i->buffer[self]= g_object_ref (buffer);
Packit bc1512
Packit bc1512
      if (format)
Packit bc1512
        i->format[self]=format;
Packit bc1512
      else
Packit bc1512
        i->format[self]=buffer->soft_format;
Packit bc1512
Packit bc1512
      if (flags == GEGL_CL_BUFFER_WRITE)
Packit bc1512
        i->conv[self] = gegl_cl_color_supported (format, buffer->soft_format);
Packit bc1512
      else
Packit bc1512
        i->conv[self] = gegl_cl_color_supported (buffer->soft_format, format);
Packit bc1512
Packit bc1512
      gegl_cl_color_babl (buffer->soft_format, &i->buf_cl_format_size[self]);
Packit bc1512
      gegl_cl_color_babl (format,              &i->op_cl_format_size [self]);
Packit bc1512
    }
Packit bc1512
  else /* GEGL_CL_BUFFER_AUX */
Packit bc1512
    {
Packit bc1512
      g_assert (buffer == NULL);
Packit bc1512
Packit bc1512
      i->buffer[self] = NULL;
Packit bc1512
      i->format[self] = NULL;
Packit bc1512
      i->conv[self]   = -1;
Packit bc1512
      i->buf_cl_format_size[self] = SIZE_MAX;
Packit bc1512
Packit bc1512
      gegl_cl_color_babl (format, &i->op_cl_format_size [self]);
Packit bc1512
    }
Packit bc1512
Packit bc1512
  i->area[self][0] = left;
Packit bc1512
  i->area[self][1] = right;
Packit bc1512
  i->area[self][2] = top;
Packit bc1512
  i->area[self][3] = bottom;
Packit bc1512
Packit bc1512
  if (flags == GEGL_CL_BUFFER_WRITE
Packit bc1512
      && (left > 0 || right > 0 || top > 0 || bottom > 0))
Packit bc1512
	g_assert(FALSE);
Packit bc1512
Packit bc1512
  if (self!=0)
Packit bc1512
    {
Packit bc1512
      /* we make all subsequently added iterators share the width and height of the first one */
Packit bc1512
      i->rect[self].width  = i->rect[0].width;
Packit bc1512
      i->rect[self].height = i->rect[0].height;
Packit bc1512
    }
Packit bc1512
  else
Packit bc1512
    {
Packit bc1512
      gint x, y, j;
Packit bc1512
Packit bc1512
      i->rois = 0;
Packit bc1512
      for (y=result->y; y < result->y + result->height; y += gegl_cl_get_iter_height ())
Packit bc1512
        for (x=result->x; x < result->x + result->width;  x += gegl_cl_get_iter_width ())
Packit bc1512
          i->rois++;
Packit bc1512
Packit bc1512
      i->roi_no = 0;
Packit bc1512
      i->roi_all = g_new0 (GeglRectangle, i->rois);
Packit bc1512
Packit bc1512
      j = 0;
Packit bc1512
      for (y=0; y < result->height; y += gegl_cl_get_iter_height ())
Packit bc1512
        for (x=0; x < result->width;  x += gegl_cl_get_iter_width ())
Packit bc1512
          {
Packit bc1512
            GeglRectangle r = {x, y,
Packit bc1512
                               MIN(gegl_cl_get_iter_width (),  result->width  - x),
Packit bc1512
                               MIN(gegl_cl_get_iter_height (), result->height - y)};
Packit bc1512
            i->roi_all[j] = r;
Packit bc1512
            j++;
Packit bc1512
          }
Packit bc1512
    }
Packit bc1512
Packit bc1512
  return self;
Packit bc1512
}
Packit bc1512
Packit bc1512
gint
Packit bc1512
gegl_buffer_cl_iterator_add (GeglBufferClIterator  *iterator,
Packit bc1512
                             GeglBuffer            *buffer,
Packit bc1512
                             const GeglRectangle   *result,
Packit bc1512
                             const Babl            *format,
Packit bc1512
                             guint                  flags,
Packit bc1512
                             GeglAbyssPolicy        abyss_policy)
Packit bc1512
{
Packit bc1512
  return gegl_buffer_cl_iterator_add_2 (iterator, buffer, result, format, flags, 0,0,0,0, abyss_policy);
Packit bc1512
}
Packit bc1512
Packit bc1512
#define OPENCL_USE_CACHE 1
Packit bc1512
Packit bc1512
gboolean
Packit bc1512
gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator, gboolean *err)
Packit bc1512
{
Packit bc1512
  GeglBufferClIterators *i = (gpointer)iterator;
Packit bc1512
  gboolean result = FALSE;
Packit bc1512
  gint no, j;
Packit bc1512
  cl_int cl_err = 0;
Packit bc1512
Packit bc1512
  if (i->is_finished)
Packit bc1512
    g_error ("%s called on finished buffer iterator", G_STRFUNC);
Packit bc1512
  if (i->iteration_no == 0)
Packit bc1512
    {
Packit bc1512
      for (no=0; no<i->iterators;no++)
Packit bc1512
        {
Packit bc1512
          if (i->buffer[no])
Packit bc1512
            {
Packit bc1512
              gint j;
Packit bc1512
              gboolean found = FALSE;
Packit bc1512
              for (j=0; j
Packit bc1512
                if (i->buffer[no]==i->buffer[j])
Packit bc1512
                  {
Packit bc1512
                    found = TRUE;
Packit bc1512
                    break;
Packit bc1512
                  }
Packit bc1512
              if (!found)
Packit bc1512
                gegl_buffer_lock (i->buffer[no]);
Packit bc1512
Packit bc1512
              if (i->flags[no] == GEGL_CL_BUFFER_WRITE
Packit bc1512
                  || (i->flags[no] == GEGL_CL_BUFFER_READ
Packit bc1512
                      && (i->area[no][0] > 0 || i->area[no][1] > 0 || i->area[no][2] > 0 || i->area[no][3] > 0)))
Packit bc1512
                {
Packit bc1512
                  gegl_buffer_cl_cache_flush (i->buffer[no], &i->rect[no]);
Packit bc1512
                }
Packit bc1512
            }
Packit bc1512
        }
Packit bc1512
    }
Packit bc1512
  else
Packit bc1512
    {
Packit bc1512
      /* complete pending write work */
Packit bc1512
      for (no=0; no<i->iterators;no++)
Packit bc1512
        {
Packit bc1512
          if (i->flags[no] == GEGL_CL_BUFFER_WRITE)
Packit bc1512
            {
Packit bc1512
              /* Wait Processing */
Packit bc1512
              cl_err = gegl_clEnqueueBarrier(gegl_cl_get_command_queue());
Packit bc1512
              if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
              /* color conversion in the GPU (output) */
Packit bc1512
              if (i->conv[no] == GEGL_CL_COLOR_CONVERT)
Packit bc1512
                for (j=0; j < i->n; j++)
Packit bc1512
                  {
Packit bc1512
                    cl_err = gegl_cl_color_conv (i->tex_op[no][j], i->tex_buf[no][j], i->size[no][j],
Packit bc1512
                                                 i->format[no], i->buffer[no]->soft_format);
Packit bc1512
                    if (cl_err == FALSE) CL_ERROR;
Packit bc1512
                  }
Packit bc1512
Packit bc1512
              /* Wait Processing */
Packit bc1512
              cl_err = gegl_clEnqueueBarrier(gegl_cl_get_command_queue());
Packit bc1512
              if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
              /* GPU -> CPU */
Packit bc1512
              for (j=0; j < i->n; j++)
Packit bc1512
                {
Packit bc1512
                  gpointer data;
Packit bc1512
Packit bc1512
                  /* tile-ize */
Packit bc1512
                  if (i->conv[no] == GEGL_CL_COLOR_NOT_SUPPORTED)
Packit bc1512
                    {
Packit bc1512
                      data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_op[no][j], CL_TRUE,
Packit bc1512
                                                     CL_MAP_READ,
Packit bc1512
                                                     0, i->size[no][j] * i->op_cl_format_size [no],
Packit bc1512
                                                     0, NULL, NULL, &cl_err);
Packit bc1512
                      if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                      /* color conversion using BABL */
Packit bc1512
                      gegl_buffer_set (i->buffer[no], &i->roi[no][j], 0, i->format[no], data, GEGL_AUTO_ROWSTRIDE);
Packit bc1512
Packit bc1512
                      cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_op[no][j], data,
Packit bc1512
                                                             0, NULL, NULL);
Packit bc1512
                      if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
                    }
Packit bc1512
                  else
Packit bc1512
#ifdef OPENCL_USE_CACHE
Packit bc1512
                    {
Packit bc1512
                      gegl_buffer_cl_cache_new (i->buffer[no], &i->roi[no][j], i->tex_buf[no][j]);
Packit bc1512
                      /* don't release this texture */
Packit bc1512
                      i->tex_buf[no][j] = NULL;
Packit bc1512
                    }
Packit bc1512
#else
Packit bc1512
                    {
Packit bc1512
                      data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_buf[no][j], CL_TRUE,
Packit bc1512
                                                     CL_MAP_READ,
Packit bc1512
                                                     0, i->size[no][j] * i->buf_cl_format_size [no],
Packit bc1512
                                                     0, NULL, NULL, &cl_err);
Packit bc1512
                      if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                      /* color conversion using BABL */
Packit bc1512
                      gegl_buffer_set (i->buffer[no], &i->roi[no][j], i->format[no], data, GEGL_AUTO_ROWSTRIDE);
Packit bc1512
Packit bc1512
                      cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_buf[no][j], data,
Packit bc1512
                                                             0, NULL, NULL);
Packit bc1512
                      if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
                    }
Packit bc1512
#endif
Packit bc1512
                }
Packit bc1512
            }
Packit bc1512
        }
Packit bc1512
Packit bc1512
      /* Run! */
Packit bc1512
      cl_err = gegl_clFinish(gegl_cl_get_command_queue());
Packit bc1512
      if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
      for (no=0; no < i->iterators; no++)
Packit bc1512
        for (j=0; j < i->n; j++)
Packit bc1512
          {
Packit bc1512
            if (i->tex_buf_from_cache [no][j])
Packit bc1512
              {
Packit bc1512
                gboolean ok = gegl_buffer_cl_cache_release (i->tex_buf[no][j]);
Packit bc1512
                g_assert (ok);
Packit bc1512
              }
Packit bc1512
Packit bc1512
            if (i->tex_buf[no][j] && !i->tex_buf_from_cache [no][j])
Packit bc1512
              gegl_clReleaseMemObject (i->tex_buf[no][j]);
Packit bc1512
Packit bc1512
            if (i->tex_op [no][j])
Packit bc1512
              gegl_clReleaseMemObject (i->tex_op [no][j]);
Packit bc1512
Packit bc1512
            i->tex    [no][j] = NULL;
Packit bc1512
            i->tex_buf[no][j] = NULL;
Packit bc1512
            i->tex_op [no][j] = NULL;
Packit bc1512
          }
Packit bc1512
    }
Packit bc1512
Packit bc1512
  g_assert (i->iterators > 0);
Packit bc1512
  result = (i->roi_no >= i->rois)? FALSE : TRUE;
Packit bc1512
Packit bc1512
  i->n = MIN(GEGL_CL_NTEX, i->rois - i->roi_no);
Packit bc1512
Packit bc1512
  /* then we iterate all */
Packit bc1512
  for (no=0; no<i->iterators;no++)
Packit bc1512
    {
Packit bc1512
      for (j = 0; j < i->n; j++)
Packit bc1512
        {
Packit bc1512
          GeglRectangle r = {i->rect[no].x + i->roi_all[i->roi_no+j].x - i->area[no][0],
Packit bc1512
                             i->rect[no].y + i->roi_all[i->roi_no+j].y - i->area[no][2],
Packit bc1512
                             i->roi_all[i->roi_no+j].width             + i->area[no][0] + i->area[no][1],
Packit bc1512
                             i->roi_all[i->roi_no+j].height            + i->area[no][2] + i->area[no][3]};
Packit bc1512
          i->roi [no][j] = r;
Packit bc1512
          i->size[no][j] = r.width * r.height;
Packit bc1512
        }
Packit bc1512
Packit bc1512
      if (i->flags[no] == GEGL_CL_BUFFER_READ)
Packit bc1512
        {
Packit bc1512
          for (j=0; j < i->n; j++)
Packit bc1512
            {
Packit bc1512
              gpointer data;
Packit bc1512
Packit bc1512
              /* un-tile */
Packit bc1512
              switch (i->conv[no])
Packit bc1512
                {
Packit bc1512
                  case GEGL_CL_COLOR_NOT_SUPPORTED:
Packit bc1512
Packit bc1512
                    {
Packit bc1512
                    gegl_buffer_cl_cache_flush (i->buffer[no], &i->roi[no][j]);
Packit bc1512
Packit bc1512
                    g_assert (i->tex_op[no][j] == NULL);
Packit bc1512
                    i->tex_op[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
Packit bc1512
                                                            CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,
Packit bc1512
                                                            i->size[no][j] * i->op_cl_format_size [no],
Packit bc1512
                                                            NULL, &cl_err);
Packit bc1512
                    if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                    /* pre-pinned memory */
Packit bc1512
                    data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_op[no][j], CL_TRUE,
Packit bc1512
                                                   CL_MAP_WRITE,
Packit bc1512
                                                   0, i->size[no][j] * i->op_cl_format_size [no],
Packit bc1512
                                                   0, NULL, NULL, &cl_err);
Packit bc1512
                    if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                    /* color conversion using BABL */
Packit bc1512
                    gegl_buffer_get (i->buffer[no], &i->roi[no][j], 1.0, i->format[no], data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
Packit bc1512
Packit bc1512
                    cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_op[no][j], data,
Packit bc1512
                                                               0, NULL, NULL);
Packit bc1512
                    if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                    i->tex[no][j] = i->tex_op[no][j];
Packit bc1512
Packit bc1512
                    break;
Packit bc1512
                    }
Packit bc1512
Packit bc1512
                  case GEGL_CL_COLOR_EQUAL:
Packit bc1512
Packit bc1512
                    {
Packit bc1512
                    i->tex_buf[no][j] = gegl_buffer_cl_cache_get (i->buffer[no], &i->roi[no][j]);
Packit bc1512
Packit bc1512
                    if (i->tex_buf[no][j])
Packit bc1512
                      i->tex_buf_from_cache [no][j] = TRUE; /* don't free texture from cache */
Packit bc1512
                    else
Packit bc1512
                      {
Packit bc1512
                        gegl_buffer_cl_cache_flush (i->buffer[no], &i->roi[no][j]);
Packit bc1512
Packit bc1512
                        g_assert (i->tex_buf[no][j] == NULL);
Packit bc1512
                        i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
Packit bc1512
                                                                 CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,
Packit bc1512
                                                                 i->size[no][j] * i->buf_cl_format_size [no],
Packit bc1512
                                                                 NULL, &cl_err);
Packit bc1512
                        if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                        /* pre-pinned memory */
Packit bc1512
                        data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_buf[no][j], CL_TRUE,
Packit bc1512
                                                       CL_MAP_WRITE,
Packit bc1512
                                                       0, i->size[no][j] * i->buf_cl_format_size [no],
Packit bc1512
                                                       0, NULL, NULL, &cl_err);
Packit bc1512
                        if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                        /* color conversion will be performed in the GPU later */
Packit bc1512
                        gegl_buffer_get (i->buffer[no], &i->roi[no][j], 1.0, i->buffer[no]->soft_format, data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
Packit bc1512
Packit bc1512
                        cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_buf[no][j], data,
Packit bc1512
                                                               0, NULL, NULL);
Packit bc1512
                        if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
                      }
Packit bc1512
Packit bc1512
                    i->tex[no][j] = i->tex_buf[no][j];
Packit bc1512
Packit bc1512
                    break;
Packit bc1512
                    }
Packit bc1512
Packit bc1512
                  case GEGL_CL_COLOR_CONVERT:
Packit bc1512
Packit bc1512
                    {
Packit bc1512
                    i->tex_buf[no][j] = gegl_buffer_cl_cache_get (i->buffer[no], &i->roi[no][j]);
Packit bc1512
Packit bc1512
                    if (i->tex_buf[no][j])
Packit bc1512
                      i->tex_buf_from_cache [no][j] = TRUE; /* don't free texture from cache */
Packit bc1512
                    else
Packit bc1512
                      {
Packit bc1512
                        gegl_buffer_cl_cache_flush (i->buffer[no], &i->roi[no][j]);
Packit bc1512
Packit bc1512
                        g_assert (i->tex_buf[no][j] == NULL);
Packit bc1512
                        i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
Packit bc1512
                                                                 CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,
Packit bc1512
                                                                 i->size[no][j] * i->buf_cl_format_size [no],
Packit bc1512
                                                                 NULL, &cl_err);
Packit bc1512
                        if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                        /* pre-pinned memory */
Packit bc1512
                        data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_buf[no][j], CL_TRUE,
Packit bc1512
                                                       CL_MAP_WRITE,
Packit bc1512
                                                       0, i->size[no][j] * i->buf_cl_format_size [no],
Packit bc1512
                                                       0, NULL, NULL, &cl_err);
Packit bc1512
                        if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                        /* color conversion will be performed in the GPU later */
Packit bc1512
                        gegl_buffer_get (i->buffer[no], &i->roi[no][j], 1.0, i->buffer[no]->soft_format, data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
Packit bc1512
Packit bc1512
                        cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_buf[no][j], data,
Packit bc1512
                                                               0, NULL, NULL);
Packit bc1512
                        if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
                      }
Packit bc1512
Packit bc1512
                    g_assert (i->tex_op[no][j] == NULL);
Packit bc1512
                    i->tex_op[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
Packit bc1512
                                                            CL_MEM_READ_WRITE,
Packit bc1512
                                                            i->size[no][j] * i->op_cl_format_size [no],
Packit bc1512
                                                            NULL, &cl_err);
Packit bc1512
                    if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                    /* color conversion in the GPU (input) */
Packit bc1512
                    g_assert (i->tex_buf[no][j] && i->tex_op[no][j]);
Packit bc1512
                    cl_err = gegl_cl_color_conv (i->tex_buf[no][j], i->tex_op[no][j], i->size[no][j],
Packit bc1512
                                                 i->buffer[no]->soft_format, i->format[no]);
Packit bc1512
                    if (cl_err == FALSE) CL_ERROR;
Packit bc1512
Packit bc1512
                    i->tex[no][j] = i->tex_op[no][j];
Packit bc1512
Packit bc1512
                    break;
Packit bc1512
                    }
Packit bc1512
                }
Packit bc1512
            }
Packit bc1512
Packit bc1512
          /* Wait Processing */
Packit bc1512
          cl_err = gegl_clEnqueueBarrier(gegl_cl_get_command_queue());
Packit bc1512
          if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
        }
Packit bc1512
      else if (i->flags[no] == GEGL_CL_BUFFER_WRITE)
Packit bc1512
        {
Packit bc1512
          for (j=0; j < i->n; j++)
Packit bc1512
            {
Packit bc1512
              switch (i->conv[no])
Packit bc1512
                {
Packit bc1512
                  case GEGL_CL_COLOR_NOT_SUPPORTED:
Packit bc1512
Packit bc1512
                  {
Packit bc1512
                  g_assert (i->tex_op[no][j] == NULL);
Packit bc1512
                  i->tex_op[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
Packit bc1512
                                                          CL_MEM_ALLOC_HOST_PTR | CL_MEM_WRITE_ONLY,
Packit bc1512
                                                          i->size[no][j] * i->op_cl_format_size [no],
Packit bc1512
                                                          NULL, &cl_err);
Packit bc1512
                  if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                  i->tex[no][j] = i->tex_op[no][j];
Packit bc1512
Packit bc1512
                  break;
Packit bc1512
                  }
Packit bc1512
Packit bc1512
                  case GEGL_CL_COLOR_EQUAL:
Packit bc1512
Packit bc1512
                  {
Packit bc1512
                  g_assert (i->tex_buf[no][j] == NULL);
Packit bc1512
                  i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
Packit bc1512
                                                           CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, /* cache */
Packit bc1512
                                                           i->size[no][j] * i->buf_cl_format_size [no],
Packit bc1512
                                                           NULL, &cl_err);
Packit bc1512
                  if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                  i->tex[no][j] = i->tex_buf[no][j];
Packit bc1512
Packit bc1512
                  break;
Packit bc1512
                  }
Packit bc1512
Packit bc1512
                  case GEGL_CL_COLOR_CONVERT:
Packit bc1512
Packit bc1512
                  {
Packit bc1512
                  g_assert (i->tex_buf[no][j] == NULL);
Packit bc1512
                  i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
Packit bc1512
                                                           CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, /* cache */
Packit bc1512
                                                           i->size[no][j] * i->buf_cl_format_size [no],
Packit bc1512
                                                           NULL, &cl_err);
Packit bc1512
                  if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                  g_assert (i->tex_op[no][j] == NULL);
Packit bc1512
                  i->tex_op[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
Packit bc1512
                                                          CL_MEM_READ_WRITE,
Packit bc1512
                                                          i->size[no][j] * i->op_cl_format_size [no],
Packit bc1512
                                                          NULL, &cl_err);
Packit bc1512
                  if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
                  i->tex[no][j] = i->tex_op[no][j];
Packit bc1512
Packit bc1512
                  break;
Packit bc1512
                  }
Packit bc1512
               }
Packit bc1512
            }
Packit bc1512
        }
Packit bc1512
      else if (i->flags[no] == GEGL_CL_BUFFER_AUX)
Packit bc1512
        {
Packit bc1512
          for (j=0; j < i->n; j++)
Packit bc1512
            {
Packit bc1512
              g_assert (i->tex_op[no][j] == NULL);
Packit bc1512
              i->tex_op[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
Packit bc1512
                                                      CL_MEM_READ_WRITE,
Packit bc1512
                                                      i->size[no][j] * i->op_cl_format_size [no],
Packit bc1512
                                                      NULL, &cl_err);
Packit bc1512
              if (cl_err != CL_SUCCESS) CL_ERROR;
Packit bc1512
Packit bc1512
              i->tex[no][j] = i->tex_op[no][j];
Packit bc1512
            }
Packit bc1512
        }
Packit bc1512
    }
Packit bc1512
Packit bc1512
  i->roi_no += i->n;
Packit bc1512
Packit bc1512
  i->iteration_no++;
Packit bc1512
Packit bc1512
  if (result == FALSE)
Packit bc1512
    {
Packit bc1512
      for (no=0; no<i->iterators;no++)
Packit bc1512
        {
Packit bc1512
          if (i->buffer[no])
Packit bc1512
            {
Packit bc1512
              gint j;
Packit bc1512
              gboolean found = FALSE;
Packit bc1512
              for (j=0; j
Packit bc1512
                if (i->buffer[no]==i->buffer[j])
Packit bc1512
                  {
Packit bc1512
                    found = TRUE;
Packit bc1512
                    break;
Packit bc1512
                  }
Packit bc1512
              if (!found)
Packit bc1512
                gegl_buffer_unlock (i->buffer[no]);
Packit bc1512
Packit bc1512
              g_object_unref (i->buffer[no]);
Packit bc1512
            }
Packit bc1512
        }
Packit bc1512
Packit bc1512
      i->is_finished = TRUE;
Packit bc1512
Packit bc1512
      g_free (i->roi_all);
Packit bc1512
      g_slice_free (GeglBufferClIterators, i);
Packit bc1512
    }
Packit bc1512
Packit bc1512
  *err = FALSE;
Packit bc1512
  return result;
Packit bc1512
Packit bc1512
error:
Packit bc1512
Packit bc1512
  for (no=0; no<i->iterators;no++)
Packit bc1512
    for (j=0; j < i->n; j++)
Packit bc1512
      {
Packit bc1512
        if (i->tex_buf[no][j]) gegl_clReleaseMemObject (i->tex_buf[no][j]);
Packit bc1512
        if (i->tex_op [no][j]) gegl_clReleaseMemObject (i->tex_op [no][j]);
Packit bc1512
Packit bc1512
        i->tex    [no][j] = NULL;
Packit bc1512
        i->tex_buf[no][j] = NULL;
Packit bc1512
        i->tex_op [no][j] = NULL;
Packit bc1512
      }
Packit bc1512
Packit bc1512
  *err = TRUE;
Packit bc1512
  return FALSE;
Packit bc1512
}
Packit bc1512
Packit bc1512
GeglBufferClIterator *
Packit bc1512
gegl_buffer_cl_iterator_new (GeglBuffer          *buffer,
Packit bc1512
                             const GeglRectangle *roi,
Packit bc1512
                             const Babl          *format,
Packit bc1512
                             guint                flags,
Packit bc1512
                             GeglAbyssPolicy      abyss_policy)
Packit bc1512
{
Packit bc1512
  GeglBufferClIterator *i = (gpointer)g_slice_new0 (GeglBufferClIterators);
Packit bc1512
  /* Because the iterator is nulled above, we can forgo explicitly setting
Packit bc1512
   * i->is_finished to FALSE. */
Packit bc1512
  gegl_buffer_cl_iterator_add (i, buffer, roi, format, flags, abyss_policy);
Packit bc1512
  return i;
Packit bc1512
}
Packit bc1512
Packit bc1512
#undef CL_ERROR