From: Yang Rong Date: Wed, 4 Sep 2013 08:58:07 +0000 (+0800) Subject: Add clEnqueueReadBufferRect api. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=62525183e17f2a4c74f9a72634bbe95f13b1b267;p=contrib%2Fbeignet.git Add clEnqueueReadBufferRect api. Signed-off-by: Yang Rong Reviewed-by: Zhigang Gong --- diff --git a/src/cl_api.c b/src/cl_api.c index 30d0b11..389676c 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 */