[Beignet] [PATCH] Implement clEnqueueReadImage and clEnqueueWriteImage.
Dag Lem
dag at nimrod.no
Sat May 18 07:53:28 PDT 2013
Signed-off-by: Dag Lem <dag at nimrod.no>
---
src/cl_api.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 180 insertions(+), 17 deletions(-)
diff --git a/src/cl_api.c b/src/cl_api.c
index daafbf0..a134dcc 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -970,8 +970,83 @@ clEnqueueReadImage(cl_command_queue command_queue,
const cl_event * event_wait_list,
cl_event * event)
{
- NOT_IMPLEMENTED;
- return 0;
+ cl_int err = CL_SUCCESS;
+ void* src_ptr;
+
+ CHECK_QUEUE(command_queue);
+ CHECK_IMAGE(image);
+ if (command_queue->ctx != image->ctx) {
+ err = CL_INVALID_CONTEXT;
+ goto error;
+ }
+
+ if (blocking_read != CL_TRUE)
+ NOT_IMPLEMENTED;
+
+ if (!origin || !region || origin[0] + region[0] > image->w || origin[1] + region[1] > image->h || origin[2] + region[2] > image->depth) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (!row_pitch)
+ row_pitch = image->bpp*region[0];
+ else if (row_pitch < image->bpp*region[0]) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (image->slice_pitch) {
+ if (!slice_pitch)
+ slice_pitch = row_pitch*region[1];
+ else if (slice_pitch < row_pitch*region[1]) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+ }
+ else if (slice_pitch) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (!ptr) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (image->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) {
+ err = CL_INVALID_OPERATION;
+ goto error;
+ }
+
+ if (!(src_ptr = clMapBufferIntel(image, &err))) {
+ goto error;
+ }
+
+ size_t offset = image->bpp*origin[0] + image->row_pitch*origin[1] + image->slice_pitch*origin[2];
+ src_ptr = (char*)src_ptr + offset;
+
+ if (row_pitch == image->row_pitch && slice_pitch == image->slice_pitch) {
+ memcpy(ptr, src_ptr, slice_pitch ? slice_pitch*region[2] : row_pitch*region[1]);
+ }
+ else {
+ cl_uint y, z;
+ for (z = 0; z < region[2]; z++) {
+ const char* src = src_ptr;
+ char* dst = ptr;
+ for (y = 0; y < region[1]; y++) {
+ memcpy(dst, src, image->bpp*region[0]);
+ src += image->row_pitch;
+ dst += row_pitch;
+ }
+ src_ptr = (char*)src_ptr + image->slice_pitch;
+ ptr = (char*)ptr + slice_pitch;
+ }
+ }
+
+ err = clUnmapBufferIntel(image);
+
+error:
+ return err;
}
cl_int
@@ -980,15 +1055,90 @@ clEnqueueWriteImage(cl_command_queue command_queue,
cl_bool blocking_write,
const size_t * origin,
const size_t * region,
- size_t input_row_pitch,
- size_t input_slice_pitch,
+ size_t row_pitch,
+ size_t slice_pitch,
const void * ptr,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event)
{
- NOT_IMPLEMENTED;
- return 0;
+ cl_int err = CL_SUCCESS;
+ void* dst_ptr;
+
+ CHECK_QUEUE(command_queue);
+ CHECK_IMAGE(image);
+ if (command_queue->ctx != image->ctx) {
+ err = CL_INVALID_CONTEXT;
+ goto error;
+ }
+
+ if (blocking_write != CL_TRUE)
+ NOT_IMPLEMENTED;
+
+ if (!origin || !region || origin[0] + region[0] > image->w || origin[1] + region[1] > image->h || origin[2] + region[2] > image->depth) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (!row_pitch)
+ row_pitch = image->bpp*region[0];
+ else if (row_pitch < image->bpp*region[0]) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (image->slice_pitch) {
+ if (!slice_pitch)
+ slice_pitch = row_pitch*region[1];
+ else if (slice_pitch < row_pitch*region[1]) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+ }
+ else if (slice_pitch) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (!ptr) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (image->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)) {
+ err = CL_INVALID_OPERATION;
+ goto error;
+ }
+
+ if (!(dst_ptr = clMapBufferIntel(image, &err))) {
+ goto error;
+ }
+
+ size_t offset = image->bpp*origin[0] + image->row_pitch*origin[1] + image->slice_pitch*origin[2];
+ dst_ptr = (char*)dst_ptr + offset;
+
+ if (row_pitch == image->row_pitch && slice_pitch == image->slice_pitch) {
+ memcpy(dst_ptr, ptr, slice_pitch ? slice_pitch*region[2] : row_pitch*region[1]);
+ }
+ else {
+ cl_uint y, z;
+ for (z = 0; z < region[2]; z++) {
+ const char* src = ptr;
+ char* dst = dst_ptr;
+ for (y = 0; y < region[1]; y++) {
+ memcpy(dst, src, image->bpp*region[0]);
+ src += row_pitch;
+ dst += image->row_pitch;
+ }
+ ptr = (char*)ptr + slice_pitch;
+ dst_ptr = (char*)dst_ptr + image->slice_pitch;
+ }
+ }
+
+ err = clUnmapBufferIntel(image);
+
+error:
+ return err;
}
cl_int
@@ -1077,33 +1227,46 @@ clEnqueueMapImage(cl_command_queue command_queue,
CHECK_QUEUE(command_queue);
CHECK_IMAGE(image);
if (command_queue->ctx != image->ctx) {
- err = CL_INVALID_CONTEXT;
- goto error;
+ err = CL_INVALID_CONTEXT;
+ goto error;
}
if (blocking_map != CL_TRUE)
- NOT_IMPLEMENTED;
+ NOT_IMPLEMENTED;
if (!origin || !region || origin[0] + region[0] > image->w || origin[1] + region[1] > image->h || origin[2] + region[2] > image->depth) {
- err = CL_INVALID_VALUE;
- goto error;
+ err = CL_INVALID_VALUE;
+ goto error;
}
if (!image_row_pitch || (image->slice_pitch && !image_slice_pitch)) {
- err = CL_INVALID_VALUE;
- goto error;
+ err = CL_INVALID_VALUE;
+ goto error;
}
*image_row_pitch = image->row_pitch;
if (image_slice_pitch)
- *image_slice_pitch = image->slice_pitch;
+ *image_slice_pitch = image->slice_pitch;
+
+ if ((map_flags & CL_MAP_READ &&
+ image->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) ||
+ (map_flags & (CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION) &&
+ image->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)))
+ {
+ err = CL_INVALID_OPERATION;
+ goto error;
+ }
- size_t offset = origin[0]*image->bpp + origin[1]*image->row_pitch + origin[2]*image->slice_pitch;
- ptr = (char*)cl_mem_map(image) + offset;
+ if (!(ptr = clMapBufferIntel(image, &err))) {
+ goto error;
+ }
+
+ size_t offset = image->bpp*origin[0] + image->row_pitch*origin[1] + image->slice_pitch*origin[2];
+ ptr = (char*)ptr + offset;
error:
if (errcode_ret)
- *errcode_ret = err;
+ *errcode_ret = err;
return ptr;
}
--
1.8.1.4
More information about the Beignet
mailing list