[Beignet] [PATCH 1/3] Add clEnqueueReadBufferRect api.
Zhigang Gong
zhigang.gong at linux.intel.com
Sun Sep 8 20:16:58 PDT 2013
LGTM, thanks.
On Wed, Sep 04, 2013 at 04:58:07PM +0800, Yang Rong wrote:
>
> 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
>
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet
More information about the Beignet
mailing list