[Beignet] [PATCH 1/3] Add clEnqueueReadBufferRect api.

Yang Rong rong.r.yang at intel.com
Wed Sep 4 01:58:07 PDT 2013


Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
 src/cl_api.c     | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/cl_enqueue.c | 51 ++++++++++++++++++++++++++++++++++++++++-
 src/cl_enqueue.h | 27 ++++++++++++----------
 3 files changed, 133 insertions(+), 15 deletions(-)

diff --git a/src/cl_api.c b/src/cl_api.c
index 30d0b11..4fd0c7e 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -1243,8 +1243,74 @@ clEnqueueReadBufferRect(cl_command_queue command_queue,
                         const cl_event * event_wait_list,
                         cl_event *       event)
 {
-  NOT_IMPLEMENTED;
-  return 0;
+  cl_int err = CL_SUCCESS;
+  enqueue_data *data, no_wait_data = { 0 };
+
+  CHECK_QUEUE(command_queue);
+  CHECK_MEM(buffer);
+
+  if (command_queue->ctx != buffer->ctx) {
+    err = CL_INVALID_CONTEXT;
+    goto error;
+  }
+
+  if (blocking_read != CL_TRUE)
+    NOT_IMPLEMENTED;
+
+  if (!ptr || !region || region[0] == 0 || region[1] == 0 || region[2] == 0) {
+    err = CL_INVALID_VALUE;
+    goto error;
+  }
+
+  if(buffer_row_pitch == 0)
+    buffer_row_pitch = region[0];
+  if(buffer_slice_pitch == 0)
+    buffer_slice_pitch = region[1] * buffer_row_pitch;
+
+  if(host_row_pitch == 0)
+    host_row_pitch = region[0];
+  if(host_slice_pitch == 0)
+    host_slice_pitch = region[1] * host_row_pitch;
+
+  if (buffer_row_pitch < region[0] ||
+      host_row_pitch < region[0]) {
+    err = CL_INVALID_VALUE;
+    goto error;
+  }
+
+  if ((buffer_slice_pitch < region[1] * buffer_row_pitch || buffer_slice_pitch % buffer_row_pitch != 0 ) ||
+      (host_slice_pitch < region[1] * host_row_pitch || host_slice_pitch % host_row_pitch != 0 )) {
+    err = CL_INVALID_VALUE;
+    goto error;
+  }
+
+  if ((buffer_origin[2]+region[2])*buffer_slice_pitch + (buffer_origin[1]+region[1])*buffer_row_pitch + buffer_origin[0] + region[0] > buffer->size) {
+    err = CL_INVALID_VALUE;
+    goto error;
+  }
+
+  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list, event, buffer->ctx);
+
+  data = &no_wait_data;
+  data->type        = EnqueueReadBufferRect;
+  data->mem_obj     = buffer;
+  data->ptr         = ptr;
+  data->origin[0]   = buffer_origin[0]; data->origin[1] = buffer_origin[1]; data->origin[2] = buffer_origin[2];
+  data->host_origin[0]  = host_origin[0]; data->host_origin[1] = host_origin[1]; data->host_origin[2] = host_origin[2];
+  data->region[0]   = region[0];  data->region[1] = region[1];  data->region[2] = region[2];
+  data->row_pitch   = buffer_row_pitch;
+  data->slice_pitch = buffer_slice_pitch;
+  data->host_row_pitch   = host_row_pitch;
+  data->host_slice_pitch = host_slice_pitch;
+
+  if(handle_events(command_queue, num_events_in_wait_list, event_wait_list,
+                   event, data, CL_COMMAND_READ_BUFFER_RECT) == CL_ENQUEUE_EXECUTE_IMM) {
+    err = cl_enqueue_handle(data);
+    if(event) cl_event_set_status(*event, CL_COMPLETE);
+  }
+
+ error:
+  return err;
 }
 
 cl_int
diff --git a/src/cl_enqueue.c b/src/cl_enqueue.c
index 290f6a0..b1065d6 100644
--- a/src/cl_enqueue.c
+++ b/src/cl_enqueue.c
@@ -45,6 +45,53 @@ error:
   return err;
 }
 
+cl_int cl_enqueue_read_buffer_rect(enqueue_data* data)
+{
+  cl_int err = CL_SUCCESS;
+  void* src_ptr;
+  void* dst_ptr;
+
+  const size_t* origin = data->origin;
+  const size_t* host_origin = data->host_origin;
+  const size_t* region = data->region;
+
+  if (!(src_ptr = cl_mem_map_auto(data->mem_obj))) {
+    err = CL_MAP_FAILURE;
+    goto error;
+  }
+
+   size_t offset = origin[0] + data->row_pitch*origin[1] + data->slice_pitch*origin[2];
+   src_ptr = (char*)src_ptr + offset;
+
+   offset = host_origin[0] + data->host_row_pitch*host_origin[1] + data->host_slice_pitch*host_origin[2];
+   dst_ptr = (char *)data->ptr + offset;
+
+   if (!origin[0] && !host_origin[0] && data->row_pitch == data->host_row_pitch &&
+       (region[2] == 1 || (!origin[1] && !host_origin[1] && data->slice_pitch == data->host_slice_pitch)))
+   {
+     memcpy(dst_ptr, src_ptr, region[2] == 1 ? data->row_pitch*region[1] : data->slice_pitch*region[2]);
+   }
+   else {
+     cl_uint y, z;
+     for (z = 0; z < region[2]; z++) {
+       const char* src = src_ptr;
+       char* dst = dst_ptr;
+       for (y = 0; y < region[1]; y++) {
+         memcpy(dst, src, region[0]);
+         src += data->row_pitch;
+         dst += data->host_row_pitch;
+       }
+       src_ptr = (char*)src_ptr + data->slice_pitch;
+       dst_ptr = (char*)dst_ptr + data->host_slice_pitch;
+     }
+   }
+
+  err = cl_mem_unmap_auto(data->mem_obj);
+
+error:
+  return err;
+}
+
 cl_int cl_enqueue_write_buffer(enqueue_data *data)
 {
   cl_int err = CL_SUCCESS;
@@ -171,7 +218,7 @@ cl_int cl_enqueue_map_buffer(enqueue_data *data)
     assert(buffer->host_ptr);
     memcpy(buffer->host_ptr + data->offset, ptr, data->size);
   }
-  
+
 error:
   return err;
 }
@@ -261,6 +308,8 @@ cl_int cl_enqueue_handle(enqueue_data* data)
   switch(data->type) {
     case EnqueueReadBuffer:
       return cl_enqueue_read_buffer(data);
+    case EnqueueReadBufferRect:
+      return cl_enqueue_read_buffer_rect(data);
     case EnqueueWriteBuffer:
       return cl_enqueue_write_buffer(data);
     case EnqueueReadImage:
diff --git a/src/cl_enqueue.h b/src/cl_enqueue.h
index 7dc8ceb..848c7c4 100644
--- a/src/cl_enqueue.h
+++ b/src/cl_enqueue.h
@@ -44,18 +44,21 @@ typedef enum {
 } enqueue_type;
 
 typedef struct _enqueue_data {
-  enqueue_type      type;          /* Command type */
-  cl_mem            mem_obj;       /* Enqueue's cl_mem */
-  cl_command_queue  queue;         /* Command queue */
-  size_t            offset;        /* Mem object's offset */
-  size_t            size;          /* Size */
-  size_t            origin[3];     /* Origin */
-  size_t            region[3];     /* Region */
-  size_t            row_pitch;     /* Row pitch */
-  size_t            slice_pitch;   /* Slice pitch */
-  cl_map_flags      map_flags;     /* Map flags */
-  const void *      const_ptr;     /* Const ptr for memory read */
-  void *            ptr;           /* ptr for write and return value */
+  enqueue_type      type;             /* Command type */
+  cl_mem            mem_obj;          /* Enqueue's cl_mem */
+  cl_command_queue  queue;            /* Command queue */
+  size_t            offset;           /* Mem object's offset */
+  size_t            size;             /* Size */
+  size_t            origin[3];        /* Origin */
+  size_t            host_origin[3];   /* Origin */
+  size_t            region[3];        /* Region */
+  size_t            row_pitch;        /* Row pitch */
+  size_t            slice_pitch;      /* Slice pitch */
+  size_t            host_row_pitch;   /* Host row pitch, used in read/write buffer rect */
+  size_t            host_slice_pitch; /* Host slice pitch, used in read/write buffer rect */
+  cl_map_flags      map_flags;        /* Map flags */
+  const void *      const_ptr;        /* Const ptr for memory read */
+  void *            ptr;              /* ptr for write and return value */
 } enqueue_data;
 
 /* Do real enqueue commands */
-- 
1.8.1.2



More information about the Beignet mailing list