|
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
|