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