summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Steckelmacher <steckdenis@yahoo.fr>2011-08-01 15:36:21 +0200
committerDenis Steckelmacher <steckdenis@yahoo.fr>2011-08-01 15:36:21 +0200
commit570e86e46c84ffc8ce3fc6bb8f8963e3a31e4106 (patch)
treec42de236b2b8b1526b250eff02ee3c58c4435010
parentce8975073e81ae54c8542646d146b43c741048e4 (diff)
Implement clEnqueueMapImage
-rw-r--r--src/api/api_enqueue.cpp50
-rw-r--r--src/core/cpu/device.cpp22
-rw-r--r--src/core/cpu/device.h13
-rw-r--r--src/core/cpu/worker.cpp14
-rw-r--r--src/core/events.cpp114
-rw-r--r--src/core/events.h34
-rw-r--r--tests/test_commandqueue.cpp20
7 files changed, 252 insertions, 15 deletions
diff --git a/src/api/api_enqueue.cpp b/src/api/api_enqueue.cpp
index 6ea5ef5..39b07b5 100644
--- a/src/api/api_enqueue.cpp
+++ b/src/api/api_enqueue.cpp
@@ -478,7 +478,55 @@ clEnqueueMapImage(cl_command_queue command_queue,
cl_event * event,
cl_int * errcode_ret)
{
- return 0;
+ cl_int rs;
+
+ if (!errcode_ret)
+ errcode_ret = &rs;
+
+ *errcode_ret = CL_SUCCESS;
+
+ if (!command_queue)
+ {
+ *errcode_ret = CL_INVALID_COMMAND_QUEUE;
+ return 0;
+ }
+
+ Coal::MapImageEvent *command = new Coal::MapImageEvent(
+ (Coal::CommandQueue *)command_queue,
+ (Coal::Image2D *)image,
+ map_flags, origin, region,
+ num_events_in_wait_list, (const Coal::Event **)event_wait_list, errcode_ret
+ );
+
+ if (*errcode_ret != CL_SUCCESS)
+ {
+ delete command;
+ return 0;
+ }
+
+ if (!image_row_pitch ||
+ (image->type() == Coal::MemObject::Image3D && !image_slice_pitch))
+ {
+ *errcode_ret = CL_INVALID_VALUE;
+ delete command;
+ return 0;
+ }
+
+ *errcode_ret = queueEvent(command_queue, command, event, blocking_map);
+
+ if (*errcode_ret != CL_SUCCESS)
+ {
+ return 0;
+ }
+ else
+ {
+ *image_row_pitch = command->row_pitch();
+
+ if (image_slice_pitch)
+ *image_slice_pitch = command->slice_pitch();
+
+ return command->ptr();
+ }
}
cl_int
diff --git a/src/core/cpu/device.cpp b/src/core/cpu/device.cpp
index 907cdf0..b7ac22e 100644
--- a/src/core/cpu/device.cpp
+++ b/src/core/cpu/device.cpp
@@ -121,13 +121,33 @@ cl_int CPUDevice::initEventDeviceData(Event *event)
{
MapBufferEvent *e = (MapBufferEvent *)event;
CPUBuffer *buf = (CPUBuffer *)e->buffer()->deviceBuffer(this);
- char *data = (char *)buf->data();
+ unsigned char *data = (unsigned char *)buf->data();
data += e->offset();
e->setPtr((void *)data);
break;
}
+ case Event::MapImage:
+ {
+ MapImageEvent *e = (MapImageEvent *)event;
+ Image2D *image = (Image2D *)e->buffer();
+ CPUBuffer *buf = (CPUBuffer *)image->deviceBuffer(this);
+ unsigned char *data = (unsigned char *)buf->data();
+
+ data = imageData(data,
+ e->origin(0),
+ e->origin(1),
+ e->origin(2),
+ image->row_pitch(),
+ image->slice_pitch(),
+ image->pixel_size());
+
+ e->setPtr((void *)data);
+ e->setRowPitch(image->row_pitch());
+ e->setSlicePitch(image->slice_pitch());
+ break;
+ }
case Event::UnmapMemObject:
// Nothing do to
break;
diff --git a/src/core/cpu/device.h b/src/core/cpu/device.h
index fd38ff7..52128f1 100644
--- a/src/core/cpu/device.h
+++ b/src/core/cpu/device.h
@@ -6,6 +6,19 @@
#include <pthread.h>
#include <list>
+static unsigned char *imageData(unsigned char *base, size_t x, size_t y,
+ size_t z, size_t row_pitch, size_t slice_pitch,
+ unsigned int bytes_per_pixel)
+{
+ unsigned char *result = base;
+
+ result += (z * slice_pitch) +
+ (y * row_pitch) +
+ (x * bytes_per_pixel);
+
+ return result;
+}
+
namespace Coal
{
diff --git a/src/core/cpu/worker.cpp b/src/core/cpu/worker.cpp
index 550dadf..b1344ef 100644
--- a/src/core/cpu/worker.cpp
+++ b/src/core/cpu/worker.cpp
@@ -13,19 +13,6 @@
using namespace Coal;
-static unsigned char *imageData(unsigned char *base, size_t x, size_t y,
- size_t z, size_t row_pitch, size_t slice_pitch,
- unsigned int bytes_per_pixel)
-{
- unsigned char *result = base;
-
- result += (z * slice_pitch) +
- (y * row_pitch) +
- (x * bytes_per_pixel);
-
- return result;
-}
-
void *worker(void *data)
{
CPUDevice *device = (CPUDevice *)data;
@@ -173,6 +160,7 @@ void *worker(void *data)
break;
}
case Event::MapBuffer:
+ case Event::MapImage:
// All was already done in CPUBuffer::initEventDeviceData()
break;
diff --git a/src/core/events.cpp b/src/core/events.cpp
index 7cf6415..9bdabc6 100644
--- a/src/core/events.cpp
+++ b/src/core/events.cpp
@@ -215,6 +215,11 @@ size_t MapBufferEvent::cb() const
return p_cb;
}
+cl_map_flags MapBufferEvent::flags() const
+{
+ return p_map_flags;
+}
+
void *MapBufferEvent::ptr() const
{
return p_ptr;
@@ -225,6 +230,115 @@ void MapBufferEvent::setPtr(void *ptr)
p_ptr = ptr;
}
+MapImageEvent::MapImageEvent(CommandQueue *parent,
+ Image2D *image,
+ cl_map_flags map_flags,
+ const size_t origin[3],
+ const size_t region[3],
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret)
+: BufferEvent (parent, image, num_events_in_wait_list, event_wait_list, errcode_ret)
+{
+ if (*errcode_ret != CL_SUCCESS) return;
+
+ // Check flags
+ if (map_flags & ~(CL_MAP_READ | CL_MAP_WRITE))
+ {
+ *errcode_ret = CL_INVALID_VALUE;
+ return;
+ }
+
+ // Copy the vectors
+ if (origin)
+ std::memcpy(&p_origin, origin, 3 * sizeof(size_t));
+ else
+ std::memset(&p_origin, 0, 3 * sizeof(size_t));
+
+ for (unsigned int i=0; i<3; ++i)
+ {
+ if (!region[i])
+ {
+ *errcode_ret = CL_INVALID_VALUE;
+ return;
+ }
+
+ p_region[i] = region[i];
+ }
+
+ // Multiply the elements (for images)
+ p_region[0] *= image->pixel_size();
+ p_origin[0] *= image->pixel_size();
+
+ // Check for overflow
+ if (image->type() == MemObject::Image2D &&
+ (origin[2] != 0 || region[2] != 1))
+ {
+ *errcode_ret = CL_INVALID_VALUE;
+ return;
+ }
+
+ // Check for out-of-bounds
+ if ((p_origin[0] + p_region[0]) > image->row_pitch() ||
+ (p_origin[1] + p_region[1]) * image->row_pitch() > image->slice_pitch() ||
+ (p_origin[2] + p_region[2]) * image->slice_pitch() > image->size())
+ {
+ *errcode_ret = CL_INVALID_VALUE;
+ return;
+ }
+}
+
+Event::Type MapImageEvent::type() const
+{
+ return Event::MapImage;
+}
+
+
+cl_map_flags MapImageEvent::flags() const
+{
+ return p_map_flags;
+}
+
+size_t MapImageEvent::origin (unsigned int index) const
+{
+ return p_origin[index];
+}
+
+size_t MapImageEvent::region (unsigned int index) const
+{
+ return p_region[index];
+}
+
+size_t MapImageEvent::row_pitch() const
+{
+ return p_row_pitch;
+}
+
+size_t MapImageEvent::slice_pitch() const
+{
+ return p_slice_pitch;
+}
+
+void *MapImageEvent::ptr() const
+{
+ return p_ptr;
+}
+
+void MapImageEvent::setRowPitch (size_t row_pitch)
+{
+ p_row_pitch = row_pitch;
+}
+
+void MapImageEvent::setSlicePitch (size_t slice_pitch)
+{
+ p_slice_pitch = slice_pitch;
+}
+
+void MapImageEvent::setPtr (void *ptr)
+{
+ p_ptr = ptr;
+}
+
UnmapBufferEvent::UnmapBufferEvent(CommandQueue *parent,
MemObject *buffer,
void *mapped_addr,
diff --git a/src/core/events.h b/src/core/events.h
index 7ed08dd..75b2833 100644
--- a/src/core/events.h
+++ b/src/core/events.h
@@ -100,6 +100,7 @@ class MapBufferEvent : public BufferEvent
size_t offset() const;
size_t cb() const;
+ cl_map_flags flags() const;
void *ptr() const;
void setPtr(void *ptr);
@@ -109,6 +110,39 @@ class MapBufferEvent : public BufferEvent
void *p_ptr;
};
+class MapImageEvent : public BufferEvent
+{
+ public:
+ MapImageEvent(CommandQueue *parent,
+ Image2D *image,
+ cl_map_flags map_flags,
+ const size_t origin[3],
+ const size_t region[3],
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret);
+
+ Type type() const;
+
+ size_t origin(unsigned int index) const;
+ size_t region(unsigned int index) const;
+ cl_map_flags flags() const;
+
+ void *ptr() const;
+ size_t row_pitch() const;
+ size_t slice_pitch() const;
+
+ void setPtr(void *ptr);
+ void setRowPitch(size_t row_pitch);
+ void setSlicePitch(size_t slice_pitch);
+
+ private:
+ cl_map_flags p_map_flags;
+ size_t p_origin[3], p_region[3];
+ void *p_ptr;
+ size_t p_slice_pitch, p_row_pitch;
+};
+
class UnmapBufferEvent : public BufferEvent
{
public:
diff --git a/tests/test_commandqueue.cpp b/tests/test_commandqueue.cpp
index 2bb57f6..c8d9834 100644
--- a/tests/test_commandqueue.cpp
+++ b/tests/test_commandqueue.cpp
@@ -779,6 +779,26 @@ START_TEST (test_copy_image_buffer)
"copying data around isn't working the expected way"
);
+ // Map the image and check pointers
+ unsigned char *mapped;
+ size_t row_pitch;
+
+ origin[0] = 0;
+ origin[1] = 0;
+ origin[2] = 0;
+
+ mapped = (unsigned char *)clEnqueueMapImage(queue, image, 1, CL_MAP_READ,
+ origin, region, &row_pitch, 0, 0,
+ 0, 0, &result);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to map an image"
+ );
+ fail_if(
+ mapped != image_buffer,
+ "mapped aread doesn't match host ptr"
+ );
+
clReleaseEvent(event);
clReleaseMemObject(image);
clReleaseMemObject(buffer);