[gegl] Fixing bugs on cl-cache
- From: Ãyvind KolÃs <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] Fixing bugs on cl-cache
- Date: Tue, 20 Mar 2012 13:54:15 +0000 (UTC)
commit 2bafae384cf28671cb426e98236ffd664e50393a
Author: Victor Oliveira <victormatheus gmail com>
Date: Tue Mar 13 08:54:05 2012 -0300
Fixing bugs on cl-cache
* all code that changes cache lists are with mutexes
* changing g_array to g_list because it's easier to catch bugs this way
* putting some code between #if 0 for future conference
gegl/buffer/gegl-buffer-cl-cache.c | 225 ++++++++++++++-------------------
gegl/buffer/gegl-buffer-cl-iterator.c | 19 +++
2 files changed, 116 insertions(+), 128 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-cl-cache.c b/gegl/buffer/gegl-buffer-cl-cache.c
index 4d99ad4..049ffdc 100644
--- a/gegl/buffer/gegl-buffer-cl-cache.c
+++ b/gegl/buffer/gegl-buffer-cl-cache.c
@@ -9,8 +9,6 @@
#include "gegl-buffer-cl-cache.h"
#include "opencl/gegl-cl.h"
-//#define GEGL_CL_BUFFER_CACHE_LOG
-
typedef struct
{
GeglBuffer *buffer;
@@ -19,7 +17,7 @@ typedef struct
gboolean valid;
} CacheEntry;
-static GArray *cache_entries = NULL;
+static GList *cache_entries = NULL;
typedef struct
{
@@ -29,25 +27,19 @@ typedef struct
gboolean valid;
} CacheBuffer;
-static GArray *cache_buffer = NULL; /* this is used in color conversions from the cache */
+static GList *cache_buffer = NULL; /* this is used in color conversions from the cache */
+
+static GStaticMutex cache_mutex = G_STATIC_MUTEX_INIT;
cl_mem
gegl_buffer_cl_cache_get (GeglBuffer *buffer,
const GeglRectangle *roi)
{
- gint i;
+ GList *elem;
- if (!roi)
- roi = &buffer->extent;
-
- if (G_UNLIKELY (!cache_entries))
+ for (elem=cache_entries; elem; elem=elem->next)
{
- 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);
+ CacheEntry *e = elem->data;
if (e->valid && e->buffer == buffer
&& gegl_rectangle_equal (&e->roi, roi))
{
@@ -62,22 +54,20 @@ gegl_buffer_cl_cache_new (GeglBuffer *buffer,
const GeglRectangle *roi,
cl_mem tex)
{
- CacheEntry e;
+ g_static_mutex_lock (&cache_mutex);
- if (!roi)
- roi = &buffer->extent;
+ {
+ CacheEntry *e = g_slice_new (CacheEntry);
- e.buffer = buffer;
- e.roi = *roi;
- e.tex = tex;
- e.valid = TRUE;
+ e->buffer = buffer;
+ e->roi = *roi;
+ e->tex = tex;
+ e->valid = TRUE;
- if (G_UNLIKELY (!cache_entries))
- {
- cache_entries = g_array_new (TRUE, TRUE, sizeof (CacheEntry));
- }
+ cache_entries = g_list_prepend (cache_entries, e);
+ }
- g_array_append_val (cache_entries, e);
+ g_static_mutex_unlock (&cache_mutex);
}
gboolean
@@ -85,130 +75,136 @@ gegl_buffer_cl_cache_merge (GeglBuffer *buffer,
const GeglRectangle *roi)
{
size_t size;
- gint i;
+ GList *elem;
GeglRectangle tmp;
cl_int cl_err = 0;
- if (!roi)
- roi = &buffer->extent;
-
gegl_cl_color_babl (buffer->format, &size);
- if (G_UNLIKELY (!cache_entries))
+ for (elem=cache_entries; elem; elem=elem->next)
{
- 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);
+ CacheEntry *entry = elem->data;
if (entry->valid && entry->buffer == buffer
- && gegl_rectangle_intersect (&tmp, roi, &entry->roi))
+ && (!roi || 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;
+ if (cl_err != CL_SUCCESS) goto error;
/* 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;
+ if (cl_err != CL_SUCCESS) goto error;
}
}
return TRUE;
+
+error:
+ /* XXX : result is corrupted */
+ return FALSE;
}
static gboolean
-cache_buffer_find_invalid (int *index)
+cache_buffer_find_invalid (gpointer *data)
{
- int i;
- for (i=0; i<cache_buffer->len; i++)
+ GList *elem;
+
+ for (elem=cache_buffer; elem; elem=elem->next)
{
- CacheBuffer *cb = &g_array_index (cache_buffer, CacheBuffer, i);
+ CacheBuffer *cb = elem->data;
if (!cb->valid)
{
- *index = i;
+ *data = cb;
return TRUE;
}
}
- *index = -1;
+ *data = NULL;
return FALSE;
}
+
static gboolean
-cache_entry_find_invalid (int *index)
+cache_entry_find_invalid (gpointer *data)
{
- int i;
- for (i=0; i<cache_entries->len; i++)
+ GList *elem;
+
+ for (elem=cache_entries; elem; elem=elem->next)
{
- CacheEntry *e = &g_array_index (cache_entries, CacheEntry, i);
- if (!e->valid)
+ CacheEntry *cb = elem->data;
+ if (!cb->valid)
{
- *index = i;
+ *data = cb;
return TRUE;
}
}
- *index = -1;
+ *data = NULL;
return FALSE;
}
-
void
gegl_buffer_cl_cache_remove (GeglBuffer *buffer,
const GeglRectangle *roi)
{
GeglRectangle tmp;
- gint i;
-
- if (!roi)
- roi = &buffer->extent;
-
- if (G_UNLIKELY (!cache_buffer))
- {
- cache_buffer = g_array_new (TRUE, TRUE, sizeof (CacheBuffer));
- }
-
- if (G_UNLIKELY (!cache_entries))
- {
- cache_entries = g_array_new (TRUE, TRUE, sizeof (CacheEntry));
- }
+ GList *elem;
+ gpointer data;
- for (i=0; i<cache_buffer->len; i++)
+ for (elem=cache_buffer; elem; elem=elem->next)
{
- CacheBuffer *cb = &g_array_index (cache_buffer, CacheBuffer, i);
+ CacheBuffer *cb = elem->data;
if (cb->valid && cb->buffer_origin == buffer
- && gegl_rectangle_intersect (&tmp, &cb->roi, roi))
+ && (!roi || gegl_rectangle_intersect (&tmp, &cb->roi, roi)))
{
gegl_buffer_destroy (cb->buffer);
cb->valid = FALSE;
}
}
- for (i=0; i<cache_entries->len; i++)
+ for (elem=cache_entries; elem; elem=elem->next)
{
- CacheEntry *e = &g_array_index (cache_entries, CacheEntry, i);
+ CacheEntry *e = elem->data;
if (e->valid && e->buffer == buffer
- && gegl_rectangle_intersect (&tmp, roi, &e->roi))
+ && (!roi || gegl_rectangle_intersect (&tmp, roi, &e->roi)))
{
gegl_clReleaseMemObject (e->tex);
e->valid = FALSE;
}
}
- while (cache_buffer_find_invalid (&i))
- g_array_remove_index (cache_buffer, i);
+ g_static_mutex_lock (&cache_mutex);
- while (cache_entry_find_invalid (&i))
- g_array_remove_index (cache_entries, i);
+ while (cache_buffer_find_invalid (&data))
+ {
+ g_slice_free (CacheBuffer, data);
+ cache_buffer = g_list_remove (cache_buffer, data);
+ }
+
+ while (cache_entry_find_invalid (&data))
+ {
+ g_slice_free (CacheEntry, data);
+ cache_entries = g_list_remove (cache_entries, data);
+ }
+
+ g_static_mutex_unlock (&cache_mutex);
+
+#if 0
+ g_printf ("-- ");
+ for (elem=cache_buffer; elem; elem=elem->next)
+ {
+ CacheBuffer *cb = elem->data;
+ g_printf ("%p %p {%d, %d, %d, %d} %d | ", cb->buffer, cb->buffer_origin, cb->roi.x, cb->roi.y, cb->roi.width, cb->roi.height, cb->valid);
+ }
+ g_printf ("\n");
+#endif
}
@@ -216,21 +212,9 @@ void
gegl_buffer_cl_cache_invalidate (GeglBuffer *buffer,
const GeglRectangle *roi)
{
- if (!roi)
- roi = &buffer->extent;
-
- 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);
- }
+ 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;}
@@ -244,24 +228,15 @@ gegl_buffer_cl_cache_from (GeglBuffer *buffer,
{
size_t buf_size, dest_size;
cl_mem tex_dest = NULL;
-
- gint i;
+ GList *elem_cache, *elem_buffer;
gegl_cl_color_op conv = gegl_cl_color_supported (buffer->format, format);
gegl_cl_color_babl (buffer->format, &buf_size);
gegl_cl_color_babl (format, &dest_size);
- if (G_UNLIKELY (!cache_entries))
+ for (elem_cache=cache_entries; elem_cache; elem_cache=elem_cache->next)
{
- cache_entries = g_array_new (TRUE, TRUE, sizeof (CacheEntry));
- }
-
- if (cache_entries->len == 0)
- return FALSE;
-
- for (i=0; i<cache_entries->len; i++)
- {
- CacheEntry *entry = &g_array_index (cache_entries, CacheEntry, i);
+ CacheEntry *entry = elem_cache->data;
if (entry->valid && entry->buffer == buffer
&& gegl_rectangle_contains (&entry->roi, roi))
@@ -282,16 +257,10 @@ gegl_buffer_cl_cache_from (GeglBuffer *buffer,
case GEGL_CL_COLOR_CONVERT:
{
- gint i;
- if (G_UNLIKELY (!cache_buffer))
+ for (elem_buffer=cache_buffer; elem_buffer; elem_buffer=elem_buffer->next)
{
- cache_buffer = g_array_new (TRUE, TRUE, sizeof (CacheBuffer));
- }
-
- for (i=0; i<cache_buffer->len; i++)
- {
- CacheBuffer *cb = &g_array_index (cache_buffer, CacheBuffer, i);
+ CacheBuffer *cb = elem_buffer->data;
if (cb->valid && cb->buffer &&
cb->buffer_origin == buffer &&
cb->buffer->format == format &&
@@ -309,18 +278,18 @@ gegl_buffer_cl_cache_from (GeglBuffer *buffer,
{
gpointer data;
- CacheBuffer cb;
-
- if (G_UNLIKELY (!cache_buffer))
- {
- cache_buffer = g_array_new (TRUE, TRUE, sizeof (CacheBuffer));
- }
-
- cb.buffer = gegl_buffer_new (&entry->roi, format);
- cb.buffer_origin = buffer;
- cb.roi = entry->roi;
- cb.valid = TRUE;
- g_array_append_val (cache_buffer, cb);
+ CacheBuffer *cb;
+
+ g_static_mutex_lock (&cache_mutex);
+ {
+ cb = g_slice_new (CacheBuffer);
+ cb->buffer = gegl_buffer_new (&entry->roi, format);
+ cb->buffer_origin = buffer;
+ cb->roi = entry->roi;
+ cb->valid = TRUE;
+ cache_buffer = g_list_prepend (cache_buffer, cb);
+ }
+ g_static_mutex_unlock (&cache_mutex);
tex_dest = gegl_clCreateBuffer (gegl_cl_get_context (),
CL_MEM_WRITE_ONLY,
@@ -337,7 +306,7 @@ gegl_buffer_cl_cache_from (GeglBuffer *buffer,
0, NULL, NULL, &cl_err);
if (cl_err != CL_SUCCESS) CL_ERROR;
- gegl_buffer_set (cb.buffer, &entry->roi, format, data, GEGL_AUTO_ROWSTRIDE);
+ gegl_buffer_set (cb->buffer, &entry->roi, format, data, GEGL_AUTO_ROWSTRIDE);
cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), tex_dest, data,
0, NULL, NULL);
@@ -346,7 +315,7 @@ gegl_buffer_cl_cache_from (GeglBuffer *buffer,
cl_err = gegl_clFinish(gegl_cl_get_command_queue());
if (cl_err != CL_SUCCESS) CL_ERROR;
- gegl_buffer_get (cb.buffer,
+ gegl_buffer_get (cb->buffer,
1.0,
roi,
format,
diff --git a/gegl/buffer/gegl-buffer-cl-iterator.c b/gegl/buffer/gegl-buffer-cl-iterator.c
index 54f05e9..bbaae16 100644
--- a/gegl/buffer/gegl-buffer-cl-iterator.c
+++ b/gegl/buffer/gegl-buffer-cl-iterator.c
@@ -171,6 +171,8 @@ gegl_buffer_cl_iterator_add (GeglBufferClIterator *iterator,
return gegl_buffer_cl_iterator_add_2 (iterator, buffer, result, format, flags, 0,0,0,0);
}
+#define OPENCL_USE_CACHE 1
+
gboolean
gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator, gboolean *err)
{
@@ -253,11 +255,28 @@ gegl_buffer_cl_iterator_next (GeglBufferClIterator *iterator, gboolean *err)
if (cl_err != CL_SUCCESS) CL_ERROR;
}
else
+#ifdef OPENCL_USE_CACHE
{
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;
}
+#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 using BABL */
+ gegl_buffer_set (i->buffer[no], &i->roi[no][j], i->format[no], 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;
+ }
+#endif
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]