[gegl] OpenCl Cache for Buffer regions
- From: Ãyvind KolÃs <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] OpenCl Cache for Buffer regions
- Date: Tue, 20 Mar 2012 13:52:39 +0000 (UTC)
commit c3e7b5e6a7a96d0053861f43a3124fcb50bcedaf
Author: Victor Oliveira <victormatheus gmail com>
Date: Mon Feb 6 10:52:31 2012 -0200
OpenCl Cache for Buffer regions
Adapting buffer to use OpenCl cache
gegl/buffer/Makefile.am | 3 +-
gegl/buffer/gegl-buffer-access.c | 17 ++
gegl/buffer/gegl-buffer-cl-cache.c | 334 +++++++++++++++++++++++++++++++++
gegl/buffer/gegl-buffer-cl-cache.h | 37 ++++
gegl/buffer/gegl-buffer-cl-iterator.c | 110 ++++++------
gegl/buffer/gegl-buffer.c | 3 +
gegl/gegl-config.c | 2 +
gegl/opencl/gegl-cl-init.c | 6 +
gegl/opencl/gegl-cl-init.h | 6 +
gegl/opencl/gegl-cl-types.h | 4 +-
10 files changed, 466 insertions(+), 56 deletions(-)
---
diff --git a/gegl/buffer/Makefile.am b/gegl/buffer/Makefile.am
index 10f9628..a1b3c18 100644
--- a/gegl/buffer/Makefile.am
+++ b/gegl/buffer/Makefile.am
@@ -21,6 +21,7 @@ libbuffer_la_SOURCES = \
gegl-buffer-index.h \
gegl-buffer-iterator.c \
gegl-buffer-cl-iterator.c \
+ gegl-buffer-cl-cache.c \
gegl-buffer-linear.c \
gegl-buffer-save.c \
gegl-buffer-load.c \
@@ -50,6 +51,7 @@ libbuffer_la_SOURCES = \
gegl-buffer-private.h \
gegl-buffer-iterator.h \
gegl-buffer-cl-iterator.h \
+ gegl-buffer-cl-cache.h \
gegl-buffer-load.h \
gegl-buffer-save.h \
gegl-buffer-types.h \
@@ -76,4 +78,3 @@ libbuffer_la_SOURCES = \
gegl-tile-handler-log.h \
gegl-tile-handler-zoom.h \
gegl-id-pool.h
-
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index b063022..3f2f8c9 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -947,6 +947,20 @@ gegl_buffer_get_unlocked (GeglBuffer *buffer,
}
#endif
+ if (cl_state.is_accelerated)
+ {
+ if (GEGL_FLOAT_EQUAL (scale, 1.0))
+ {
+ if (gegl_buffer_cl_cache_from (buffer, rect, dest_buf, format, rowstride))
+ return;
+ }
+ else
+ {
+ /* doesn't support scaling in the GPU */
+ gegl_buffer_cl_cache_invalidate (buffer, rect);
+ }
+ }
+
if (!rect && scale == 1.0)
{
gegl_buffer_iterate (buffer, NULL, dest_buf, rowstride, FALSE, format, 0);
@@ -1181,6 +1195,9 @@ gegl_buffer_clear (GeglBuffer *dst,
pxsize = babl_format_get_bytes_per_pixel (dst->format);
+ if (cl_state.is_accelerated)
+ gegl_buffer_cl_cache_remove (dst, dst_rect);
+
/* FIXME: this can be even further optimized by special casing it so
* that fully voided tiles are dropped.
*/
diff --git a/gegl/buffer/gegl-buffer-cl-cache.c b/gegl/buffer/gegl-buffer-cl-cache.c
new file mode 100644
index 0000000..c1433b1
--- /dev/null
+++ b/gegl/buffer/gegl-buffer-cl-cache.c
@@ -0,0 +1,334 @@
+#include <glib.h>
+
+#include "gegl.h"
+#include "gegl-utils.h"
+#include "gegl-types-internal.h"
+#include "gegl-buffer-types.h"
+#include "gegl-buffer.h"
+#include "gegl-buffer-private.h"
+#include "gegl-buffer-cl-cache.h"
+#include "opencl/gegl-cl.h"
+
+//#define GEGL_CL_BUFFER_CACHE_LOG
+
+typedef struct
+{
+ GeglBuffer *buffer;
+ GeglRectangle roi;
+ cl_mem tex;
+} CacheEntry;
+
+static GArray *cache_entries = NULL;
+
+typedef struct
+{
+ GeglBuffer *buffer;
+ GeglBuffer *buffer_origin;
+ GeglRectangle roi;
+} CacheBuffer;
+
+static CacheBuffer cache_buffer = {NULL, NULL, {-1, -1, -1, -1}};
+
+cl_mem
+gegl_buffer_cl_cache_get (GeglBuffer *buffer,
+ const GeglRectangle *roi)
+{
+ gint i;
+
+ if (!roi)
+ roi = &buffer->extent;
+
+ if (G_UNLIKELY (!cache_entries))
+ {
+ cache_entries = g_array_new (TRUE, TRUE, sizeof (CacheEntry));
+ }
+
+ for (i=0; i<cache_entries->len; i++)
+ {
+ CacheEntry *e = &g_array_index (cache_entries, CacheEntry, i);
+ if (e->buffer == buffer && gegl_rectangle_equal (&e->roi, roi))
+ {
+ return e->tex;
+ }
+ }
+ return NULL;
+}
+
+void
+gegl_buffer_cl_cache_new (GeglBuffer *buffer,
+ const GeglRectangle *roi,
+ cl_mem tex)
+{
+ CacheEntry e;
+
+ if (!roi)
+ roi = &buffer->extent;
+
+ e.buffer = buffer;
+ e.roi = *roi;
+ e.tex = tex;
+
+ if (G_UNLIKELY (!cache_entries))
+ {
+ cache_entries = g_array_new (TRUE, TRUE, sizeof (CacheEntry));
+ }
+
+ g_array_append_val (cache_entries, e);
+}
+
+gboolean
+gegl_buffer_cl_cache_merge (GeglBuffer *buffer,
+ const GeglRectangle *roi)
+{
+ size_t size;
+ gint i;
+ GeglRectangle tmp;
+ cl_int cl_err = 0;
+
+ if (!roi)
+ roi = &buffer->extent;
+
+ gegl_cl_color_babl (buffer->format, NULL, &size);
+
+ if (G_UNLIKELY (!cache_entries))
+ {
+ cache_entries = g_array_new (TRUE, TRUE, sizeof (CacheEntry));
+ }
+
+ for (i=0; i<cache_entries->len; i++)
+ {
+ CacheEntry *entry = &g_array_index (cache_entries, CacheEntry, i);
+ if (entry->buffer == buffer &&
+ gegl_rectangle_intersect (&tmp, roi, &entry->roi))
+ {
+ gpointer data;
+
+ data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), entry->tex, CL_TRUE,
+ CL_MAP_READ, 0, roi->width * roi->height * size,
+ 0, NULL, NULL, &cl_err);
+ if (cl_err != CL_SUCCESS) return FALSE;
+
+ /* tile-ize */
+ gegl_buffer_set (entry->buffer, &entry->roi, entry->buffer->format, data, GEGL_AUTO_ROWSTRIDE);
+
+ cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), entry->tex, data,
+ 0, NULL, NULL);
+ if (cl_err != CL_SUCCESS) return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+void
+gegl_buffer_cl_cache_remove (GeglBuffer *buffer,
+ const GeglRectangle *roi)
+{
+ GeglRectangle tmp;
+ gint i;
+ gboolean found;
+
+ if (!roi)
+ roi = &buffer->extent;
+
+ if (cache_buffer.buffer_origin == buffer &&
+ gegl_rectangle_intersect (&tmp, &cache_buffer.roi, roi))
+ {
+ gegl_buffer_destroy (cache_buffer.buffer);
+ cache_buffer.buffer_origin = NULL;
+ }
+
+ if (G_UNLIKELY (!cache_entries))
+ {
+ cache_entries = g_array_new (TRUE, TRUE, sizeof (CacheEntry));
+ }
+
+ do
+ {
+ found = FALSE;
+ for (i=0; i<cache_entries->len; i++)
+ {
+ CacheEntry *e = &g_array_index (cache_entries, CacheEntry, i);
+ if (e->buffer == buffer &&
+ gegl_rectangle_intersect (&tmp, roi, &e->roi))
+ {
+ gegl_clReleaseMemObject (e->tex);
+ g_array_remove_index_fast (cache_entries, i);
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ while (found);
+}
+
+void
+gegl_buffer_cl_cache_invalidate (GeglBuffer *buffer,
+ const GeglRectangle *roi)
+{
+ if (G_UNLIKELY (!cache_entries))
+ {
+ cache_entries = g_array_new (TRUE, TRUE, sizeof (CacheEntry));
+ return;
+ }
+
+ if (cache_entries->len > 0)
+ {
+ gegl_buffer_cl_cache_merge (buffer, roi);
+ gegl_clFinish (gegl_cl_get_command_queue ());
+ gegl_buffer_cl_cache_remove (buffer, roi);
+ }
+}
+
+#define CL_ERROR {g_printf("[OpenCL] Error in %s:%d %s - %s\n", __FILE__, __LINE__, __func__, gegl_cl_errstring(cl_err)); goto error;}
+
+gboolean
+gegl_buffer_cl_cache_from (GeglBuffer *buffer,
+ const GeglRectangle *roi,
+ gpointer dest_buf,
+ const Babl *format,
+ gint rowstride)
+{
+ size_t buf_size, dest_size;
+ cl_mem tex_dest = NULL;
+
+ gint i;
+
+ gegl_cl_color_op conv = gegl_cl_color_supported (buffer->format, format);
+ gegl_cl_color_babl (buffer->format, NULL, &buf_size);
+ gegl_cl_color_babl (format, NULL, &dest_size);
+
+ if (G_UNLIKELY (!cache_entries))
+ {
+ cache_entries = g_array_new (TRUE, TRUE, sizeof (CacheEntry));
+ }
+
+ if (cache_entries->len == 0)
+ return FALSE;
+
+ if (roi->width >= 256 && roi->height >= 256) /* no point in using the GPU to get small textures */
+ for (i=0; i<cache_entries->len; i++)
+ {
+ CacheEntry *entry = &g_array_index (cache_entries, CacheEntry, i);
+ if (entry->buffer == buffer && gegl_rectangle_contains (&entry->roi, roi))
+ {
+ cl_int cl_err;
+ const size_t origin_buf[3] = {(entry->roi.x - roi->x) * buf_size, roi->y - entry->roi.y, 0};
+ const size_t region_buf[3] = {(roi->width) * buf_size, roi->height, 1};
+
+ /* const size_t origin_dest[3] = {(entry->roi.x - roi->x) * dest_size, roi->y - entry->roi.y, 0};
+ const size_t region_dest[3] = {(roi->width) * dest_size, roi->height, 1}; */
+
+ const size_t origin_zero[3] = {0, 0, 0};
+
+ switch (conv)
+ {
+ case GEGL_CL_COLOR_NOT_SUPPORTED:
+
+ {
+ gegl_buffer_cl_cache_invalidate (buffer, &entry->roi);
+
+ return FALSE;
+ }
+
+ case GEGL_CL_COLOR_EQUAL:
+
+ {
+ cl_err = gegl_clEnqueueReadBufferRect (gegl_cl_get_command_queue (),
+ entry->tex, TRUE,
+ origin_buf, origin_zero, region_buf,
+ 0, 0,
+ (rowstride == GEGL_AUTO_ROWSTRIDE)? 0 : rowstride, 0,
+ dest_buf,
+ 0, NULL, NULL);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+
+ gegl_clFinish (gegl_cl_get_command_queue ());
+
+ return TRUE;
+ }
+
+ case GEGL_CL_COLOR_CONVERT:
+
+ {
+ if (cache_buffer.buffer &&
+ cache_buffer.buffer_origin == buffer &&
+ cache_buffer.buffer->format == format &&
+ gegl_rectangle_contains (&cache_buffer.roi, roi))
+ {
+ gegl_buffer_get (cache_buffer.buffer,
+ 1.0,
+ roi,
+ format,
+ dest_buf,
+ rowstride);
+ return TRUE;
+ }
+ else
+ {
+ gpointer data;
+
+ if (cache_buffer.buffer)
+ {
+ gegl_buffer_destroy (cache_buffer.buffer);
+ cache_buffer.buffer_origin = NULL;
+ }
+
+ cache_buffer.buffer = gegl_buffer_new (&entry->roi, format);
+ cache_buffer.buffer_origin = buffer;
+ cache_buffer.roi = entry->roi;
+
+ tex_dest = gegl_clCreateBuffer (gegl_cl_get_context (),
+ CL_MEM_WRITE_ONLY,
+ entry->roi.width * entry->roi.height * dest_size,
+ NULL, &cl_err);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+
+ cl_err = gegl_cl_color_conv (entry->tex, tex_dest, entry->roi.width * entry->roi.height, buffer->format, format);
+ if (cl_err == FALSE) CL_ERROR;
+
+ data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), tex_dest, CL_TRUE,
+ CL_MAP_READ,
+ 0, entry->roi.width * entry->roi.height * dest_size,
+ 0, NULL, NULL, &cl_err);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+
+ gegl_buffer_set (cache_buffer.buffer, &entry->roi, format, data, GEGL_AUTO_ROWSTRIDE);
+
+ cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), tex_dest, data,
+ 0, NULL, NULL);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+
+ gegl_clFinish (gegl_cl_get_command_queue ());
+
+ gegl_buffer_get (cache_buffer.buffer,
+ 1.0,
+ roi,
+ format,
+ dest_buf,
+ rowstride);
+
+ if (tex_dest) gegl_clReleaseMemObject (tex_dest);
+
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ gegl_buffer_cl_cache_invalidate (buffer, roi);
+
+ return FALSE;
+
+error:
+
+ /* this function isn`t supposed to fail, there is no memory alloc here */
+ gegl_buffer_cl_cache_invalidate (buffer, roi);
+
+ if (tex_dest) gegl_clReleaseMemObject (tex_dest);
+
+ return FALSE;
+}
+
+#undef CL_ERROR
diff --git a/gegl/buffer/gegl-buffer-cl-cache.h b/gegl/buffer/gegl-buffer-cl-cache.h
new file mode 100644
index 0000000..4145558
--- /dev/null
+++ b/gegl/buffer/gegl-buffer-cl-cache.h
@@ -0,0 +1,37 @@
+#ifndef __GEGL_BUFFER_CL_CACHE_H__
+#define __GEGL_BUFFER_CL_CACHE_H__
+
+#include "gegl.h"
+#include "gegl-types-internal.h"
+#include "gegl-buffer-types.h"
+#include "gegl-buffer.h"
+#include "gegl-buffer-private.h"
+#include "opencl/gegl-cl.h"
+
+cl_mem
+gegl_buffer_cl_cache_get (GeglBuffer *buffer,
+ const GeglRectangle *roi);
+
+void
+gegl_buffer_cl_cache_new (GeglBuffer *buffer,
+ const GeglRectangle *roi,
+ cl_mem tex);
+gboolean
+gegl_buffer_cl_cache_merge (GeglBuffer *buffer,
+ const GeglRectangle *roi);
+
+void
+gegl_buffer_cl_cache_remove (GeglBuffer *buffer,
+ const GeglRectangle *roi);
+
+void
+gegl_buffer_cl_cache_invalidate (GeglBuffer *buffer,
+ const GeglRectangle *roi);
+
+gboolean
+gegl_buffer_cl_cache_from (GeglBuffer *buffer,
+ const GeglRectangle *roi,
+ gpointer dest_buf,
+ const Babl *format,
+ gint rowstride);
+#endif
diff --git a/gegl/buffer/gegl-buffer-cl-iterator.c b/gegl/buffer/gegl-buffer-cl-iterator.c
index bce2bbe..9456ba8 100644
--- a/gegl/buffer/gegl-buffer-cl-iterator.c
+++ b/gegl/buffer/gegl-buffer-cl-iterator.c
@@ -10,6 +10,7 @@
#include "gegl-buffer-types.h"
#include "gegl-buffer-cl-iterator.h"
+#include "gegl-buffer-cl-cache.h"
#include "gegl-buffer-private.h"
#include "gegl-tile-storage.h"
#include "gegl-utils.h"
@@ -202,18 +203,9 @@ gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator, gboolean *err)
}
else
{
- data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_buf[no][j], CL_TRUE,
- CL_MAP_READ,
- 0, i->size[no][j] * i->buf_cl_format_size [no],
- 0, NULL, NULL, &cl_err);
- if (cl_err != CL_SUCCESS) CL_ERROR;
-
- /* color conversion has already been performed in the GPU */
- gegl_buffer_set (i->buffer[no], &i->roi[no][j], i->buffer[no]->format, data, GEGL_AUTO_ROWSTRIDE);
-
- cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_buf[no][j], data,
- 0, NULL, NULL);
- if (cl_err != CL_SUCCESS) CL_ERROR;
+ gegl_buffer_cl_cache_new (i->buffer[no], &i->roi[no][j], i->tex_buf[no][j]);
+ /* don't release this texture */
+ i->tex_buf[no][j] = NULL;
}
}
}
@@ -290,26 +282,31 @@ gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator, gboolean *err)
case GEGL_CL_COLOR_EQUAL:
{
- g_assert (i->tex_buf[no][j] == NULL);
- i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
- CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,
- i->size[no][j] * i->buf_cl_format_size [no],
- NULL, &cl_err);
- if (cl_err != CL_SUCCESS) CL_ERROR;
-
- /* pre-pinned memory */
- data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_buf[no][j], CL_TRUE,
- CL_MAP_WRITE,
- 0, i->size[no][j] * i->buf_cl_format_size [no],
- 0, NULL, NULL, &cl_err);
- if (cl_err != CL_SUCCESS) CL_ERROR;
-
- /* 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, GEGL_AUTO_ROWSTRIDE);
-
- cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_buf[no][j], data,
- 0, NULL, NULL);
- if (cl_err != CL_SUCCESS) CL_ERROR;
+ i->tex_buf[no][j] = gegl_buffer_cl_cache_get (i->buffer[no], &i->roi[no][j]);
+
+ if (i->tex_buf[no][j] == NULL)
+ {
+ g_assert (i->tex_buf[no][j] == NULL);
+ i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
+ CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,
+ i->size[no][j] * i->buf_cl_format_size [no],
+ NULL, &cl_err);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+
+ /* pre-pinned memory */
+ data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_buf[no][j], CL_TRUE,
+ CL_MAP_WRITE,
+ 0, i->size[no][j] * i->buf_cl_format_size [no],
+ 0, NULL, NULL, &cl_err);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+
+ /* 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, GEGL_AUTO_ROWSTRIDE);
+
+ cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_buf[no][j], data,
+ 0, NULL, NULL);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+ }
i->tex[no][j] = i->tex_buf[no][j];
@@ -319,12 +316,31 @@ gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator, gboolean *err)
case GEGL_CL_COLOR_CONVERT:
{
- g_assert (i->tex_buf[no][j] == NULL);
- i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
- CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,
- i->size[no][j] * i->buf_cl_format_size [no],
- NULL, &cl_err);
- if (cl_err != CL_SUCCESS) CL_ERROR;
+ i->tex_buf[no][j] = gegl_buffer_cl_cache_get (i->buffer[no], &i->roi[no][j]);
+
+ if (i->tex_buf[no][j] == NULL)
+ {
+ g_assert (i->tex_buf[no][j] == NULL);
+ i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
+ CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,
+ i->size[no][j] * i->buf_cl_format_size [no],
+ NULL, &cl_err);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+
+ /* pre-pinned memory */
+ data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_buf[no][j], CL_TRUE,
+ CL_MAP_WRITE,
+ 0, i->size[no][j] * i->buf_cl_format_size [no],
+ 0, NULL, NULL, &cl_err);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+
+ /* 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, GEGL_AUTO_ROWSTRIDE);
+
+ cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_buf[no][j], data,
+ 0, NULL, NULL);
+ if (cl_err != CL_SUCCESS) CL_ERROR;
+ }
g_assert (i->tex_op[no][j] == NULL);
i->tex_op[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
@@ -333,20 +349,6 @@ gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator, gboolean *err)
NULL, &cl_err);
if (cl_err != CL_SUCCESS) CL_ERROR;
- /* pre-pinned memory */
- data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), i->tex_buf[no][j], CL_TRUE,
- CL_MAP_WRITE,
- 0, i->size[no][j] * i->buf_cl_format_size [no],
- 0, NULL, NULL, &cl_err);
- if (cl_err != CL_SUCCESS) CL_ERROR;
-
- /* 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, GEGL_AUTO_ROWSTRIDE);
-
- cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), i->tex_buf[no][j], data,
- 0, NULL, NULL);
- if (cl_err != CL_SUCCESS) CL_ERROR;
-
/* color conversion in the GPU (input) */
g_assert (i->tex_buf[no][j] && i->tex_op[no][j]);
cl_err = gegl_cl_color_conv (i->tex_buf[no][j], i->tex_op[no][j], i->size[no][j],
@@ -390,7 +392,7 @@ gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator, gboolean *err)
{
g_assert (i->tex_buf[no][j] == NULL);
i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
- CL_MEM_ALLOC_HOST_PTR | CL_MEM_WRITE_ONLY,
+ CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, /* cache */
i->size[no][j] * i->buf_cl_format_size [no],
NULL, &cl_err);
if (cl_err != CL_SUCCESS) CL_ERROR;
@@ -405,7 +407,7 @@ gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator, gboolean *err)
{
g_assert (i->tex_buf[no][j] == NULL);
i->tex_buf[no][j] = gegl_clCreateBuffer (gegl_cl_get_context (),
- CL_MEM_ALLOC_HOST_PTR | CL_MEM_WRITE_ONLY,
+ CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, /* cache */
i->size[no][j] * i->buf_cl_format_size [no],
NULL, &cl_err);
if (cl_err != CL_SUCCESS) CL_ERROR;
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index c09fef6..17a22fa 100644
--- a/gegl/buffer/gegl-buffer.c
+++ b/gegl/buffer/gegl-buffer.c
@@ -372,6 +372,9 @@ gegl_buffer_dispose (GObject *object)
gegl_buffer_sample_cleanup (buffer);
+ if (cl_state.is_accelerated)
+ gegl_buffer_cl_cache_invalidate (GEGL_BUFFER (object), NULL);
+
if (handler->source &&
GEGL_IS_TILE_STORAGE (handler->source))
{
diff --git a/gegl/gegl-config.c b/gegl/gegl-config.c
index 9232e93..90385bf 100644
--- a/gegl/gegl-config.c
+++ b/gegl/gegl-config.c
@@ -24,6 +24,8 @@
#include "gegl-types-internal.h"
#include "gegl-config.h"
+#include "opencl/gegl-cl.h"
+
G_DEFINE_TYPE (GeglConfig, gegl_config, G_TYPE_OBJECT)
static GObjectClass * parent_class = NULL;
diff --git a/gegl/opencl/gegl-cl-init.c b/gegl/opencl/gegl-cl-init.c
index 7a0ea89..da665b5 100644
--- a/gegl/opencl/gegl-cl-init.c
+++ b/gegl/opencl/gegl-cl-init.c
@@ -184,6 +184,12 @@ gegl_cl_init (GError **error)
CL_LOAD_FUNCTION (clEnqueueWriteBuffer)
CL_LOAD_FUNCTION (clEnqueueReadBuffer)
CL_LOAD_FUNCTION (clEnqueueCopyBuffer)
+ CL_LOAD_FUNCTION (clEnqueueCopyBuffer)
+ CL_LOAD_FUNCTION (clEnqueueCopyBuffer)
+ CL_LOAD_FUNCTION (clEnqueueCopyBuffer)
+ CL_LOAD_FUNCTION (clEnqueueReadBufferRect)
+ CL_LOAD_FUNCTION (clEnqueueWriteBufferRect)
+ CL_LOAD_FUNCTION (clEnqueueCopyBufferRect)
CL_LOAD_FUNCTION (clCreateImage2D)
CL_LOAD_FUNCTION (clEnqueueWriteImage)
CL_LOAD_FUNCTION (clEnqueueReadImage)
diff --git a/gegl/opencl/gegl-cl-init.h b/gegl/opencl/gegl-cl-init.h
index b69de92..583e76a 100644
--- a/gegl/opencl/gegl-cl-init.h
+++ b/gegl/opencl/gegl-cl-init.h
@@ -76,6 +76,9 @@ t_clCreateBuffer gegl_clCreateBuffer = NULL;
t_clEnqueueWriteBuffer gegl_clEnqueueWriteBuffer = NULL;
t_clEnqueueReadBuffer gegl_clEnqueueReadBuffer = NULL;
t_clEnqueueCopyBuffer gegl_clEnqueueCopyBuffer = NULL;
+t_clEnqueueReadBufferRect gegl_clEnqueueReadBufferRect = NULL;
+t_clEnqueueWriteBufferRect gegl_clEnqueueWriteBufferRect = NULL;
+t_clEnqueueCopyBufferRect gegl_clEnqueueCopyBufferRect = NULL;
t_clCreateImage2D gegl_clCreateImage2D = NULL;
t_clEnqueueWriteImage gegl_clEnqueueWriteImage = NULL;
t_clEnqueueReadImage gegl_clEnqueueReadImage = NULL;
@@ -118,6 +121,9 @@ extern t_clGetKernelWorkGroupInfo gegl_clGetKernelWorkGroupInfo;
extern t_clCreateBuffer gegl_clCreateBuffer;
extern t_clEnqueueWriteBuffer gegl_clEnqueueWriteBuffer;
extern t_clEnqueueReadBuffer gegl_clEnqueueReadBuffer;
+extern t_clEnqueueReadBufferRect gegl_clEnqueueReadBufferRect;
+extern t_clEnqueueWriteBufferRect gegl_clEnqueueWriteBufferRect;
+extern t_clEnqueueCopyBufferRect gegl_clEnqueueCopyBufferRect;
extern t_clCreateImage2D gegl_clCreateImage2D;
extern t_clEnqueueWriteImage gegl_clEnqueueWriteImage;
extern t_clEnqueueReadImage gegl_clEnqueueReadImage;
diff --git a/gegl/opencl/gegl-cl-types.h b/gegl/opencl/gegl-cl-types.h
index 4e94b76..e51fc9a 100644
--- a/gegl/opencl/gegl-cl-types.h
+++ b/gegl/opencl/gegl-cl-types.h
@@ -44,7 +44,9 @@ typedef CL_API_ENTRY cl_mem (CL_API_CALL *t_clCreateBuffer
typedef CL_API_ENTRY cl_int (CL_API_CALL *t_clEnqueueWriteBuffer ) (cl_command_queue, cl_mem, cl_bool, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *);
typedef CL_API_ENTRY cl_int (CL_API_CALL *t_clEnqueueReadBuffer ) (cl_command_queue, cl_mem, cl_bool, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *);
typedef CL_API_ENTRY cl_int (CL_API_CALL *t_clEnqueueCopyBuffer ) (cl_command_queue, cl_mem, cl_mem, size_t, size_t, size_t, cl_uint, const cl_event *, cl_event *);
-
+typedef CL_API_ENTRY cl_int (CL_API_CALL *t_clEnqueueReadBufferRect ) (cl_command_queue, cl_mem, cl_bool, const size_t [3], const size_t [3], const size_t [3], size_t, size_t, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *);
+typedef CL_API_ENTRY cl_int (CL_API_CALL *t_clEnqueueWriteBufferRect ) (cl_command_queue, cl_mem, cl_bool, const size_t [3], const size_t [3], const size_t [3], size_t, size_t, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *);
+typedef CL_API_ENTRY cl_int (CL_API_CALL *t_clEnqueueCopyBufferRect ) (cl_command_queue, cl_mem, cl_mem, const size_t [3], const size_t [3], const size_t [3], size_t, size_t, size_t, size_t, cl_uint, const cl_event *, cl_event *);
typedef CL_API_ENTRY cl_mem (CL_API_CALL *t_clCreateImage2D ) (cl_context, cl_mem_flags, const cl_image_format *, size_t, size_t, size_t, void *, cl_int *);
typedef CL_API_ENTRY cl_int (CL_API_CALL *t_clEnqueueReadImage ) (cl_command_queue, cl_mem, cl_bool, const size_t [3], const size_t [3], size_t, size_t, void *, cl_uint, const cl_event *, cl_event *);
typedef CL_API_ENTRY cl_int (CL_API_CALL *t_clEnqueueWriteImage ) (cl_command_queue, cl_mem, cl_bool, const size_t [3], const size_t [3], size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]