diff options
author | Denis Steckelmacher <steckdenis@yahoo.fr> | 2011-08-01 15:36:21 +0200 |
---|---|---|
committer | Denis Steckelmacher <steckdenis@yahoo.fr> | 2011-08-01 15:36:21 +0200 |
commit | 570e86e46c84ffc8ce3fc6bb8f8963e3a31e4106 (patch) | |
tree | c42de236b2b8b1526b250eff02ee3c58c4435010 | |
parent | ce8975073e81ae54c8542646d146b43c741048e4 (diff) |
Implement clEnqueueMapImage
-rw-r--r-- | src/api/api_enqueue.cpp | 50 | ||||
-rw-r--r-- | src/core/cpu/device.cpp | 22 | ||||
-rw-r--r-- | src/core/cpu/device.h | 13 | ||||
-rw-r--r-- | src/core/cpu/worker.cpp | 14 | ||||
-rw-r--r-- | src/core/events.cpp | 114 | ||||
-rw-r--r-- | src/core/events.h | 34 | ||||
-rw-r--r-- | tests/test_commandqueue.cpp | 20 |
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); |