[Beignet] [PATCH 2/3] Add clEnqueueWriteBufferRect api.

Zhigang Gong zhigang.gong at linux.intel.com
Sun Sep 8 20:17:29 PDT 2013


LGTM, thanks.

On Wed, Sep 04, 2013 at 04:58:08PM +0800, Yang Rong wrote:
> 
> Signed-off-by: Yang Rong <rong.r.yang at intel.com>
> ---
>  src/cl_api.c     | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  src/cl_enqueue.c | 50 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 119 insertions(+), 2 deletions(-)
> 
> diff --git a/src/cl_api.c b/src/cl_api.c
> index 4fd0c7e..3630b48 100644
> --- a/src/cl_api.c
> +++ b/src/cl_api.c
> @@ -1382,8 +1382,75 @@ clEnqueueWriteBufferRect(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_write != 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        = EnqueueWriteBufferRect;
> +  data->mem_obj     = buffer;
> +  data->const_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_WRITE_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 b1065d6..156ea8c 100644
> --- a/src/cl_enqueue.c
> +++ b/src/cl_enqueue.c
> @@ -110,6 +110,54 @@ error:
>    return err;
>  }
>  
> +cl_int cl_enqueue_write_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 (!(dst_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];
> +  dst_ptr = (char *)dst_ptr + offset;
> +
> +  offset = host_origin[0] + data->host_row_pitch*host_origin[1] + data->host_slice_pitch*host_origin[2];
> +  src_ptr = (char*)data->const_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->host_row_pitch;
> +        dst += data->row_pitch;
> +      }
> +      src_ptr = (char*)src_ptr + data->host_slice_pitch;
> +      dst_ptr = (char*)dst_ptr + data->slice_pitch;
> +    }
> +  }
> +
> +  err = cl_mem_unmap_auto(data->mem_obj);
> +
> +error:
> +  return err;
> +}
> +
> +
>  cl_int cl_enqueue_read_image(enqueue_data *data)
>  {
>    cl_int err = CL_SUCCESS;
> @@ -312,6 +360,8 @@ cl_int cl_enqueue_handle(enqueue_data* data)
>        return cl_enqueue_read_buffer_rect(data);
>      case EnqueueWriteBuffer:
>        return cl_enqueue_write_buffer(data);
> +    case EnqueueWriteBufferRect:
> +      return cl_enqueue_write_buffer_rect(data);
>      case EnqueueReadImage:
>        return cl_enqueue_read_image(data);
>      case EnqueueWriteImage:
> -- 
> 1.8.1.2
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list