[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