[Beignet] [PATCH] Implement clEnqueueReadImage and clEnqueueWriteImage.
Zhigang Gong
zhigang.gong at linux.intel.com
Sun May 19 22:58:32 PDT 2013
In general, this patch looks good to me. Could you split it to two patches?
One is for clEnqueueReadImage/WriteImage. And the other is to refine the
clEnqueueMapImage. And you may consider to merge the clEnqueueMapImage refinement
patch and the previous's clEnqueueMapImage patch.
Another issue about the clEnqueueMapImage is that if the image is a tiled
buffer, then we may need to use clMapBufferGTTIntel to map it to vma. Otherwise,
we may get a tiled mapping address which is not expected by user.
On Sat, May 18, 2013 at 04:53:28PM +0200, Dag Lem wrote:
>
> Signed-off-by: Dag Lem <dag at nimrod.no>
> ---
> src/cl_api.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 180 insertions(+), 17 deletions(-)
>
> diff --git a/src/cl_api.c b/src/cl_api.c
> index daafbf0..a134dcc 100644
> --- a/src/cl_api.c
> +++ b/src/cl_api.c
> @@ -970,8 +970,83 @@ clEnqueueReadImage(cl_command_queue command_queue,
> const cl_event * event_wait_list,
> cl_event * event)
> {
> - NOT_IMPLEMENTED;
> - return 0;
> + cl_int err = CL_SUCCESS;
> + void* src_ptr;
> +
> + CHECK_QUEUE(command_queue);
> + CHECK_IMAGE(image);
> + if (command_queue->ctx != image->ctx) {
> + err = CL_INVALID_CONTEXT;
> + goto error;
> + }
> +
> + if (blocking_read != CL_TRUE)
> + NOT_IMPLEMENTED;
> +
> + if (!origin || !region || origin[0] + region[0] > image->w || origin[1] + region[1] > image->h || origin[2] + region[2] > image->depth) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> +
> + if (!row_pitch)
> + row_pitch = image->bpp*region[0];
> + else if (row_pitch < image->bpp*region[0]) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> +
> + if (image->slice_pitch) {
> + if (!slice_pitch)
> + slice_pitch = row_pitch*region[1];
> + else if (slice_pitch < row_pitch*region[1]) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> + }
> + else if (slice_pitch) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> +
> + if (!ptr) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> +
> + if (image->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) {
> + err = CL_INVALID_OPERATION;
> + goto error;
> + }
> +
> + if (!(src_ptr = clMapBufferIntel(image, &err))) {
> + goto error;
> + }
> +
> + size_t offset = image->bpp*origin[0] + image->row_pitch*origin[1] + image->slice_pitch*origin[2];
> + src_ptr = (char*)src_ptr + offset;
> +
> + if (row_pitch == image->row_pitch && slice_pitch == image->slice_pitch) {
> + memcpy(ptr, src_ptr, slice_pitch ? slice_pitch*region[2] : row_pitch*region[1]);
> + }
> + else {
> + cl_uint y, z;
> + for (z = 0; z < region[2]; z++) {
> + const char* src = src_ptr;
> + char* dst = ptr;
> + for (y = 0; y < region[1]; y++) {
> + memcpy(dst, src, image->bpp*region[0]);
> + src += image->row_pitch;
> + dst += row_pitch;
> + }
> + src_ptr = (char*)src_ptr + image->slice_pitch;
> + ptr = (char*)ptr + slice_pitch;
> + }
> + }
> +
> + err = clUnmapBufferIntel(image);
> +
> +error:
> + return err;
> }
>
> cl_int
> @@ -980,15 +1055,90 @@ clEnqueueWriteImage(cl_command_queue command_queue,
> cl_bool blocking_write,
> const size_t * origin,
> const size_t * region,
> - size_t input_row_pitch,
> - size_t input_slice_pitch,
> + size_t row_pitch,
> + size_t slice_pitch,
> const void * ptr,
> cl_uint num_events_in_wait_list,
> const cl_event * event_wait_list,
> cl_event * event)
> {
> - NOT_IMPLEMENTED;
> - return 0;
> + cl_int err = CL_SUCCESS;
> + void* dst_ptr;
> +
> + CHECK_QUEUE(command_queue);
> + CHECK_IMAGE(image);
> + if (command_queue->ctx != image->ctx) {
> + err = CL_INVALID_CONTEXT;
> + goto error;
> + }
> +
> + if (blocking_write != CL_TRUE)
> + NOT_IMPLEMENTED;
> +
> + if (!origin || !region || origin[0] + region[0] > image->w || origin[1] + region[1] > image->h || origin[2] + region[2] > image->depth) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> +
> + if (!row_pitch)
> + row_pitch = image->bpp*region[0];
> + else if (row_pitch < image->bpp*region[0]) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> +
> + if (image->slice_pitch) {
> + if (!slice_pitch)
> + slice_pitch = row_pitch*region[1];
> + else if (slice_pitch < row_pitch*region[1]) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> + }
> + else if (slice_pitch) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> +
> + if (!ptr) {
> + err = CL_INVALID_VALUE;
> + goto error;
> + }
> +
> + if (image->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)) {
> + err = CL_INVALID_OPERATION;
> + goto error;
> + }
> +
> + if (!(dst_ptr = clMapBufferIntel(image, &err))) {
> + goto error;
> + }
> +
> + size_t offset = image->bpp*origin[0] + image->row_pitch*origin[1] + image->slice_pitch*origin[2];
> + dst_ptr = (char*)dst_ptr + offset;
> +
> + if (row_pitch == image->row_pitch && slice_pitch == image->slice_pitch) {
> + memcpy(dst_ptr, ptr, slice_pitch ? slice_pitch*region[2] : row_pitch*region[1]);
> + }
> + else {
> + cl_uint y, z;
> + for (z = 0; z < region[2]; z++) {
> + const char* src = ptr;
> + char* dst = dst_ptr;
> + for (y = 0; y < region[1]; y++) {
> + memcpy(dst, src, image->bpp*region[0]);
> + src += row_pitch;
> + dst += image->row_pitch;
> + }
> + ptr = (char*)ptr + slice_pitch;
> + dst_ptr = (char*)dst_ptr + image->slice_pitch;
> + }
> + }
> +
> + err = clUnmapBufferIntel(image);
> +
> +error:
> + return err;
> }
>
> cl_int
> @@ -1077,33 +1227,46 @@ clEnqueueMapImage(cl_command_queue command_queue,
> CHECK_QUEUE(command_queue);
> CHECK_IMAGE(image);
> if (command_queue->ctx != image->ctx) {
> - err = CL_INVALID_CONTEXT;
> - goto error;
> + err = CL_INVALID_CONTEXT;
> + goto error;
> }
>
> if (blocking_map != CL_TRUE)
> - NOT_IMPLEMENTED;
> + NOT_IMPLEMENTED;
>
> if (!origin || !region || origin[0] + region[0] > image->w || origin[1] + region[1] > image->h || origin[2] + region[2] > image->depth) {
> - err = CL_INVALID_VALUE;
> - goto error;
> + err = CL_INVALID_VALUE;
> + goto error;
> }
>
> if (!image_row_pitch || (image->slice_pitch && !image_slice_pitch)) {
> - err = CL_INVALID_VALUE;
> - goto error;
> + err = CL_INVALID_VALUE;
> + goto error;
> }
>
> *image_row_pitch = image->row_pitch;
> if (image_slice_pitch)
> - *image_slice_pitch = image->slice_pitch;
> + *image_slice_pitch = image->slice_pitch;
> +
> + if ((map_flags & CL_MAP_READ &&
> + image->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) ||
> + (map_flags & (CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION) &&
> + image->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)))
> + {
> + err = CL_INVALID_OPERATION;
> + goto error;
> + }
>
> - size_t offset = origin[0]*image->bpp + origin[1]*image->row_pitch + origin[2]*image->slice_pitch;
> - ptr = (char*)cl_mem_map(image) + offset;
> + if (!(ptr = clMapBufferIntel(image, &err))) {
> + goto error;
> + }
> +
> + size_t offset = image->bpp*origin[0] + image->row_pitch*origin[1] + image->slice_pitch*origin[2];
> + ptr = (char*)ptr + offset;
>
> error:
> if (errcode_ret)
> - *errcode_ret = err;
> + *errcode_ret = err;
> return ptr;
> }
>
> --
> 1.8.1.4
>
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet
More information about the Beignet
mailing list