summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Steckelmacher <steckdenis@yahoo.fr>2011-07-30 15:20:45 +0200
committerDenis Steckelmacher <steckdenis@yahoo.fr>2011-07-30 15:20:45 +0200
commite5f4415b7350c1f6ff59c1e0ea4a50528cfd52b2 (patch)
tree3c85297a0c6ea5acccc35291ecc8291939312fd2
parent1eaf54d98364b275fb33b7b4671b2fe660cb678b (diff)
Implement clEnqueueReadImage and clEnqueueWriteImage
-rw-r--r--src/api/api_enqueue.cpp47
-rw-r--r--src/core/cpu/worker.cpp4
-rw-r--r--src/core/events.cpp107
-rw-r--r--src/core/events.h53
-rw-r--r--src/core/memobject.cpp80
-rw-r--r--src/core/memobject.h1
-rw-r--r--tests/test_commandqueue.cpp88
-rw-r--r--tests/test_mem.cpp2
8 files changed, 358 insertions, 24 deletions
diff --git a/src/api/api_enqueue.cpp b/src/api/api_enqueue.cpp
index 8f5e550..d2ce092 100644
--- a/src/api/api_enqueue.cpp
+++ b/src/api/api_enqueue.cpp
@@ -1,6 +1,7 @@
#include <CL/cl.h>
#include <core/events.h>
+#include <core/memobject.h>
static inline cl_int queueEvent(Coal::CommandQueue *queue,
Coal::Event *command,
@@ -203,7 +204,7 @@ clEnqueueCopyBufferRect(cl_command_queue command_queue,
(Coal::MemObject *)src_buffer,
(Coal::MemObject *)dst_buffer,
src_origin, dst_origin, region, src_row_pitch, src_slice_pitch,
- dst_row_pitch, dst_slice_pitch,
+ dst_row_pitch, dst_slice_pitch, 1,
num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs
);
@@ -262,7 +263,29 @@ clEnqueueReadImage(cl_command_queue command_queue,
const cl_event * event_wait_list,
cl_event * event)
{
- return 0;
+ cl_int rs = CL_SUCCESS;
+
+ if (!command_queue)
+ return CL_INVALID_COMMAND_QUEUE;
+
+ if (!image || (image->type() != Coal::MemObject::Image2D &&
+ image->type() != Coal::MemObject::Image3D))
+ return CL_INVALID_MEM_OBJECT;
+
+ Coal::ReadImageEvent *command = new Coal::ReadImageEvent(
+ (Coal::CommandQueue *)command_queue,
+ (Coal::Image2D *)image,
+ origin, region, row_pitch, slice_pitch, (void *)ptr,
+ num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs
+ );
+
+ if (rs != CL_SUCCESS)
+ {
+ delete command;
+ return rs;
+ }
+
+ return queueEvent(command_queue, command, event, blocking_read);
}
cl_int
@@ -278,7 +301,25 @@ clEnqueueWriteImage(cl_command_queue command_queue,
const cl_event * event_wait_list,
cl_event * event)
{
- return 0;
+ cl_int rs = CL_SUCCESS;
+
+ if (!command_queue)
+ return CL_INVALID_COMMAND_QUEUE;
+
+ Coal::WriteImageEvent *command = new Coal::WriteImageEvent(
+ (Coal::CommandQueue *)command_queue,
+ (Coal::Image2D *)image,
+ origin, region, row_pitch, slice_pitch, (void *)ptr,
+ num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs
+ );
+
+ if (rs != CL_SUCCESS)
+ {
+ delete command;
+ return rs;
+ }
+
+ return queueEvent(command_queue, command, event, blocking_write);
}
cl_int
diff --git a/src/core/cpu/worker.cpp b/src/core/cpu/worker.cpp
index 595f5a1..d7606d1 100644
--- a/src/core/cpu/worker.cpp
+++ b/src/core/cpu/worker.cpp
@@ -89,6 +89,8 @@ void *worker(void *data)
case Event::ReadBufferRect:
case Event::WriteBufferRect:
case Event::CopyBufferRect:
+ case Event::ReadImage:
+ case Event::WriteImage:
{
// src = buffer and dst = mem if note copy
ReadWriteCopyBufferRectEvent *e = (ReadWriteCopyBufferRectEvent *)event;
@@ -137,7 +139,7 @@ void *worker(void *data)
e->src_slice_pitch(),
1);
- if (t == Event::WriteBufferRect)
+ if (t == Event::WriteBufferRect || t == Event::WriteImage)
std::memcpy(s, d, e->region(0)); // Write dest (memory) in src
else
std::memcpy(d, s, e->region(0)); // Write src (buffer) in dest (memory), or copy the buffers
diff --git a/src/core/events.cpp b/src/core/events.cpp
index 70264a7..b6923d7 100644
--- a/src/core/events.cpp
+++ b/src/core/events.cpp
@@ -6,6 +6,7 @@
#include <cstdlib>
#include <cstring>
+#include <iostream>
using namespace Coal;
@@ -762,6 +763,7 @@ ReadWriteCopyBufferRectEvent::ReadWriteCopyBufferRectEvent(CommandQueue *parent,
size_t src_slice_pitch,
size_t dst_row_pitch,
size_t dst_slice_pitch,
+ unsigned int bytes_per_element,
cl_uint num_events_in_wait_list,
const Event **event_wait_list,
cl_int *errcode_ret)
@@ -769,8 +771,15 @@ ReadWriteCopyBufferRectEvent::ReadWriteCopyBufferRectEvent(CommandQueue *parent,
errcode_ret)
{
// Copy the vectors
- std::memcpy(&p_src_origin, src_origin, 3 * sizeof(size_t));
- std::memcpy(&p_dst_origin, dst_origin, 3 * sizeof(size_t));
+ if (src_origin)
+ std::memcpy(&p_src_origin, src_origin, 3 * sizeof(size_t));
+ else
+ std::memset(&p_src_origin, 0, 3 * sizeof(size_t));
+
+ if (dst_origin)
+ std::memcpy(&p_dst_origin, dst_origin, 3 * sizeof(size_t));
+ else
+ std::memset(&p_dst_origin, 0, 3 * sizeof(size_t));
for (unsigned int i=0; i<3; ++i)
{
@@ -782,8 +791,14 @@ ReadWriteCopyBufferRectEvent::ReadWriteCopyBufferRectEvent(CommandQueue *parent,
p_region[i] = region[i];
}
+
+ // Multiply the elements (for images)
+ p_region[0] *= bytes_per_element;
+ p_src_origin[0] *= bytes_per_element;
+ p_dst_origin[0] *= bytes_per_element;
+
// Compute the pitches
- p_src_row_pitch = region[0];
+ p_src_row_pitch = p_region[0];
if (src_row_pitch)
{
@@ -796,7 +811,7 @@ ReadWriteCopyBufferRectEvent::ReadWriteCopyBufferRectEvent(CommandQueue *parent,
p_src_row_pitch = src_row_pitch;
}
- p_src_slice_pitch = region[1] * p_src_row_pitch;
+ p_src_slice_pitch = p_region[1] * p_src_row_pitch;
if (src_slice_pitch)
{
@@ -809,7 +824,7 @@ ReadWriteCopyBufferRectEvent::ReadWriteCopyBufferRectEvent(CommandQueue *parent,
p_src_slice_pitch = src_slice_pitch;
}
- p_dst_row_pitch = region[0];
+ p_dst_row_pitch = p_region[0];
if (dst_row_pitch)
{
@@ -822,7 +837,7 @@ ReadWriteCopyBufferRectEvent::ReadWriteCopyBufferRectEvent(CommandQueue *parent,
p_dst_row_pitch = dst_row_pitch;
}
- p_dst_slice_pitch = region[1] * p_dst_row_pitch;
+ p_dst_slice_pitch = p_region[1] * p_dst_row_pitch;
if (dst_slice_pitch)
{
@@ -886,13 +901,14 @@ CopyBufferRectEvent::CopyBufferRectEvent(CommandQueue *parent,
size_t src_slice_pitch,
size_t dst_row_pitch,
size_t dst_slice_pitch,
+ unsigned int bytes_per_element,
cl_uint num_events_in_wait_list,
const Event **event_wait_list,
cl_int *errcode_ret)
: ReadWriteCopyBufferRectEvent(parent, source, src_origin, dst_origin, region,
src_row_pitch, src_slice_pitch, dst_row_pitch,
- dst_slice_pitch, num_events_in_wait_list,
- event_wait_list, errcode_ret),
+ dst_slice_pitch, bytes_per_element,
+ num_events_in_wait_list, event_wait_list, errcode_ret),
p_destination(destination)
{
if (!destination)
@@ -902,7 +918,7 @@ CopyBufferRectEvent::CopyBufferRectEvent(CommandQueue *parent,
}
// Check for out-of-bounds
- if (src_origin[0] + region[0] > this->src_row_pitch() ||
+ if ((src_origin[0] + region[0]) * bytes_per_element > this->src_row_pitch() ||
(src_origin[1] + region[1]) * this->src_row_pitch() > this->src_slice_pitch() ||
(src_origin[2] + region[2]) * this->src_slice_pitch() > source->size())
{
@@ -910,7 +926,7 @@ CopyBufferRectEvent::CopyBufferRectEvent(CommandQueue *parent,
return;
}
- if (dst_origin[0] + region[0] > this->dst_row_pitch() ||
+ if ((dst_origin[0] + region[0]) * bytes_per_element > this->dst_row_pitch() ||
(dst_origin[1] + region[1]) * this->dst_row_pitch() > this->dst_slice_pitch() ||
(dst_origin[2] + region[2]) * this->dst_slice_pitch() > destination->size())
{
@@ -960,12 +976,13 @@ ReadWriteBufferRectEvent::ReadWriteBufferRectEvent(CommandQueue *parent,
size_t host_row_pitch,
size_t host_slice_pitch,
void *ptr,
+ unsigned int bytes_per_element,
cl_uint num_events_in_wait_list,
const Event **event_wait_list,
cl_int *errcode_ret)
: ReadWriteCopyBufferRectEvent(parent, buffer, buffer_origin, host_origin, region,
buffer_row_pitch, buffer_slice_pitch,
- host_row_pitch, host_slice_pitch,
+ host_row_pitch, host_slice_pitch, bytes_per_element,
num_events_in_wait_list, event_wait_list, errcode_ret),
p_ptr(ptr)
{
@@ -976,10 +993,11 @@ ReadWriteBufferRectEvent::ReadWriteBufferRectEvent(CommandQueue *parent,
}
// Check for out-of-bounds
- if (buffer_origin[0] + region[0] > src_row_pitch() ||
+ if ((buffer_origin[0] + region[0]) * bytes_per_element > src_row_pitch() ||
(buffer_origin[1] + region[1]) * src_row_pitch() > src_slice_pitch() ||
(buffer_origin[2] + region[2]) * src_slice_pitch() > buffer->size())
{
+ std::cout << buffer_origin[0] << '+' << region[0] << '*' << bytes_per_element << '>' << src_row_pitch() << std::endl;
*errcode_ret = CL_INVALID_VALUE;
return;
}
@@ -1005,7 +1023,7 @@ ReadBufferRectEvent::ReadBufferRectEvent (CommandQueue *parent,
cl_int *errcode_ret)
: ReadWriteBufferRectEvent(parent, buffer, buffer_origin, host_origin, region,
buffer_row_pitch, buffer_slice_pitch, host_row_pitch,
- host_slice_pitch, ptr, num_events_in_wait_list,
+ host_slice_pitch, ptr, 1, num_events_in_wait_list,
event_wait_list, errcode_ret)
{
}
@@ -1030,7 +1048,7 @@ WriteBufferRectEvent::WriteBufferRectEvent (CommandQueue *parent,
cl_int *errcode_ret)
: ReadWriteBufferRectEvent (parent, buffer, buffer_origin, host_origin, region,
buffer_row_pitch, buffer_slice_pitch, host_row_pitch,
- host_slice_pitch, ptr, num_events_in_wait_list,
+ host_slice_pitch, ptr, 1, num_events_in_wait_list,
event_wait_list, errcode_ret)
{
}
@@ -1040,3 +1058,64 @@ Event::Type WriteBufferRectEvent::type() const
return WriteBufferRect;
}
+ReadWriteImageEvent::ReadWriteImageEvent (CommandQueue *parent,
+ Image2D *image,
+ const size_t origin[3],
+ const size_t region[3],
+ size_t row_pitch,
+ size_t slice_pitch,
+ void *ptr,
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret)
+: ReadWriteBufferRectEvent(parent, image, origin, 0, region, image->row_pitch(),
+ (image->type() == MemObject::Image3D ?
+ ((Image3D *)image)->slice_pitch() :
+ 0), row_pitch, slice_pitch, ptr, image->pixel_size(),
+ num_events_in_wait_list, event_wait_list, errcode_ret)
+{
+ if (image->type() == MemObject::Image2D &&
+ (origin[2] != 0 || region[2] != 1))
+ {
+ *errcode_ret = CL_INVALID_VALUE;
+ return;
+ }
+}
+
+ReadImageEvent::ReadImageEvent(CommandQueue *parent,
+ Image2D *image,
+ const size_t origin[3],
+ const size_t region[3],
+ size_t row_pitch,
+ size_t slice_pitch,
+ void *ptr,
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret)
+: ReadWriteImageEvent(parent, image, origin, region, row_pitch, slice_pitch, ptr,
+ num_events_in_wait_list, event_wait_list, errcode_ret)
+{}
+
+Event::Type ReadImageEvent::type() const
+{
+ return Event::ReadImage;
+}
+
+WriteImageEvent::WriteImageEvent(CommandQueue *parent,
+ Image2D *image,
+ const size_t origin[3],
+ const size_t region[3],
+ size_t row_pitch,
+ size_t slice_pitch,
+ void *ptr,
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret)
+: ReadWriteImageEvent (parent, image, origin, region, row_pitch, slice_pitch, ptr,
+ num_events_in_wait_list, event_wait_list, errcode_ret)
+{}
+
+Event::Type WriteImageEvent::type() const
+{
+ return Event::WriteImage;
+}
diff --git a/src/core/events.h b/src/core/events.h
index 0376007..fe2b7b0 100644
--- a/src/core/events.h
+++ b/src/core/events.h
@@ -10,6 +10,7 @@ namespace Coal
{
class MemObject;
+class Image2D;
class Kernel;
class DeviceKernel;
class DeviceInterface;
@@ -164,6 +165,7 @@ class ReadWriteCopyBufferRectEvent : public BufferEvent
size_t src_slice_pitch,
size_t dst_row_pitch,
size_t dst_slice_pitch,
+ unsigned int bytes_per_element,
cl_uint num_events_in_wait_list,
const Event **event_wait_list,
cl_int *errcode_ret);
@@ -196,6 +198,7 @@ class CopyBufferRectEvent : public ReadWriteCopyBufferRectEvent
size_t src_slice_pitch,
size_t dst_row_pitch,
size_t dst_slice_pitch,
+ unsigned int bytes_per_element,
cl_uint num_events_in_wait_list,
const Event **event_wait_list,
cl_int *errcode_ret);
@@ -220,6 +223,7 @@ class ReadWriteBufferRectEvent : public ReadWriteCopyBufferRectEvent
size_t host_row_pitch,
size_t host_slice_pitch,
void *ptr,
+ unsigned int bytes_per_element,
cl_uint num_events_in_wait_list,
const Event **event_wait_list,
cl_int *errcode_ret);
@@ -270,6 +274,55 @@ class WriteBufferRectEvent : public ReadWriteBufferRectEvent
Type type() const;
};
+class ReadWriteImageEvent : public ReadWriteBufferRectEvent
+{
+ public:
+ ReadWriteImageEvent(CommandQueue *parent,
+ Image2D *image,
+ const size_t origin[3],
+ const size_t region[3],
+ size_t row_pitch,
+ size_t slice_pitch,
+ void *ptr,
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret);
+};
+
+class ReadImageEvent : public ReadWriteImageEvent
+{
+ public:
+ ReadImageEvent(CommandQueue *parent,
+ Image2D *image,
+ const size_t origin[3],
+ const size_t region[3],
+ size_t row_pitch,
+ size_t slice_pitch,
+ void *ptr,
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret);
+
+ Type type() const;
+};
+
+class WriteImageEvent : public ReadWriteImageEvent
+{
+ public:
+ WriteImageEvent(CommandQueue *parent,
+ Image2D *image,
+ const size_t origin[3],
+ const size_t region[3],
+ size_t row_pitch,
+ size_t slice_pitch,
+ void *ptr,
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret);
+
+ Type type() const;
+};
+
class NativeKernelEvent : public Event
{
public:
diff --git a/src/core/memobject.cpp b/src/core/memobject.cpp
index 048e4e0..32fa49d 100644
--- a/src/core/memobject.cpp
+++ b/src/core/memobject.cpp
@@ -5,6 +5,7 @@
#include <cstdlib>
#include <cstring>
+#include <iostream>
using namespace Coal;
@@ -463,6 +464,69 @@ Image2D::Image2D(Context *ctx, size_t width, size_t height, size_t row_pitch,
p_format = *format;
+ // Check format descriptor
+ switch (p_format.image_channel_data_type)
+ {
+ case CL_UNORM_INT_101010:
+ case CL_UNORM_SHORT_555:
+ case CL_UNORM_SHORT_565:
+ if (p_format.image_channel_order != CL_RGB ||
+ p_format.image_channel_order != CL_RGBx)
+ {
+ *errcode_ret = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
+ return;
+ }
+ }
+
+ switch (p_format.image_channel_order)
+ {
+ case CL_LUMINANCE:
+ case CL_INTENSITY:
+ switch (p_format.image_channel_data_type)
+ {
+ case CL_UNORM_INT8:
+ case CL_UNORM_INT16:
+ case CL_SNORM_INT8:
+ case CL_SNORM_INT16:
+ case CL_HALF_FLOAT:
+ case CL_FLOAT:
+ break;
+ default:
+ *errcode_ret = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
+ return;
+ }
+ break;
+
+ case CL_RGB:
+ case CL_RGBx:
+ switch (p_format.image_channel_data_type)
+ {
+ case CL_UNORM_SHORT_555:
+ case CL_UNORM_SHORT_565:
+ case CL_UNORM_INT_101010:
+ break;
+ default:
+ *errcode_ret = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
+ return;
+ }
+ break;
+
+ case CL_ARGB:
+ case CL_BGRA:
+ switch (p_format.image_channel_data_type)
+ {
+ case CL_UNORM_INT8:
+ case CL_SNORM_INT8:
+ case CL_SIGNED_INT8:
+ case CL_UNSIGNED_INT8:
+ break;
+ default:
+ *errcode_ret = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
+ return;
+ }
+ break;
+ }
+
// Row pitch
p_row_pitch = width * pixel_size(p_format);
@@ -636,15 +700,16 @@ size_t Image2D::pixel_size(const cl_image_format &format)
multiplier = 2;
break;
- case CL_RGB:
- case CL_RGBx:
- multiplier = 3;
- break;
-
case CL_RGBA:
case CL_ARGB:
case CL_BGRA:
multiplier = 4;
+ break;
+
+ case CL_RGBx:
+ case CL_RGB:
+ multiplier = 0; // Only special data types allowed (565, 555, etc)
+ break;
default:
return 0;
@@ -662,6 +727,11 @@ size_t Image2D::pixel_size(const cl_image_format &format)
}
}
+size_t Image2D::pixel_size() const
+{
+ return pixel_size(p_format);
+}
+
/*
* Image3D
*/
diff --git a/src/core/memobject.h b/src/core/memobject.h
index 7a91879..dce70b5 100644
--- a/src/core/memobject.h
+++ b/src/core/memobject.h
@@ -116,6 +116,7 @@ class Image2D : public MemObject
static size_t element_size(const cl_image_format &format);
static size_t pixel_size(const cl_image_format &format);
+ size_t pixel_size() const;
private:
size_t p_width, p_height, p_row_pitch;
diff --git a/tests/test_commandqueue.cpp b/tests/test_commandqueue.cpp
index ea27497..a97b1de 100644
--- a/tests/test_commandqueue.cpp
+++ b/tests/test_commandqueue.cpp
@@ -554,6 +554,93 @@ START_TEST (test_copy_buffer)
}
END_TEST
+START_TEST (test_read_write_image)
+{
+ cl_platform_id platform = 0;
+ cl_device_id device;
+ cl_context ctx;
+ cl_command_queue queue;
+ cl_mem image2d;
+ cl_int result;
+
+ unsigned char image2d_data_24bpp[3*3*4] = {
+ 255, 0, 0, 0, 0, 255, 0, 0, 128, 128, 128, 0,
+ 0, 0, 255, 0, 255, 255, 0, 0, 0, 128, 0, 0,
+ 255, 128, 0, 0, 128, 0, 255, 0, 0, 0, 0, 0
+ };
+
+ unsigned char image2d_part_24bpp[2*2*4] = {
+ 255, 0, 0, 0, 0, 255, 0, 0,
+ 0, 0, 255, 0, 255, 255, 0, 0
+ };
+
+ unsigned char image2d_buffer[3*3*4];
+ unsigned char image2d_part[2*2*4];
+
+ cl_image_format fmt;
+
+ fmt.image_channel_data_type = CL_UNORM_INT8;
+ fmt.image_channel_order = CL_RGBA;
+
+ size_t origin[3] = {0, 0, 0};
+ size_t region[3] = {3, 3, 1};
+
+ result = clGetDeviceIDs(platform, CL_DEVICE_TYPE_DEFAULT, 1, &device, 0);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to get the default device"
+ );
+
+ ctx = clCreateContext(0, 1, &device, 0, 0, &result);
+ fail_if(
+ result != CL_SUCCESS || ctx == 0,
+ "unable to create a valid context"
+ );
+
+ queue = clCreateCommandQueue(ctx, device, 0, &result);
+ fail_if(
+ result != CL_SUCCESS || queue == 0,
+ "cannot create a command queue"
+ );
+
+ image2d = clCreateImage2D(ctx, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, &fmt,
+ 3, 3, 0, image2d_buffer, &result);
+ fail_if(
+ result != CL_SUCCESS || image2d == 0,
+ "cannot create a valid 3x3 image2D"
+ );
+
+ // Write data in buffer
+ result = clEnqueueWriteImage(queue, image2d, 1, origin, region, 0, 0,
+ image2d_data_24bpp, 0, 0, 0);
+ fail_if(
+ result != CL_SUCCESS,
+ "cannot enqueue a blocking write image event"
+ );
+
+ // Read it back
+ region[0] = 2;
+ region[1] = 2;
+
+ result = clEnqueueReadImage(queue, image2d, 1, origin, region, 0, 0,
+ image2d_part, 0, 0, 0);
+ fail_if(
+ result != CL_SUCCESS,
+ "cannot enqueue a blocking read image event"
+ );
+
+ // Compare
+ fail_if(
+ std::memcmp(image2d_part, image2d_part_24bpp, sizeof(image2d_part)) != 0,
+ "reading and writing images doesn't produce the correct result"
+ );
+
+ clReleaseMemObject(image2d);
+ clReleaseCommandQueue(queue);
+ clReleaseContext(ctx);
+}
+END_TEST
+
TCase *cl_commandqueue_tcase_create(void)
{
TCase *tc = NULL;
@@ -564,5 +651,6 @@ TCase *cl_commandqueue_tcase_create(void)
tcase_add_test(tc, test_events);
tcase_add_test(tc, test_read_write_rect);
tcase_add_test(tc, test_copy_buffer);
+ tcase_add_test(tc, test_read_write_image);
return tc;
}
diff --git a/tests/test_mem.cpp b/tests/test_mem.cpp
index 18b5d04..90f6180 100644
--- a/tests/test_mem.cpp
+++ b/tests/test_mem.cpp
@@ -270,7 +270,7 @@ START_TEST (test_images)
cl_image_format fmt;
fmt.image_channel_data_type = CL_UNORM_INT8;
- fmt.image_channel_order = CL_RGBx;
+ fmt.image_channel_order = CL_RGBA;
ctx = clCreateContextFromType(0, CL_DEVICE_TYPE_CPU, 0, 0, &result);
fail_if(