[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