[Beignet] [PATCH 1/2] [opencl-2.0] enable create image 2d from buffer in clCreateImage.
He Junyan
Junyan.he at inbox.com
Fri May 22 01:07:33 PDT 2015
Some comments,
On 2015年04月03日 13:39, xionghu.luo at intel.com wrote:
> From: Luo Xionghu <xionghu.luo at intel.com>
>
> this patch allows create 2d image with a cl buffer.
>
> Signed-off-by: Luo Xionghu <xionghu.luo at intel.com>
> ---
> src/cl_api.c | 3 ++-
> src/cl_mem.c | 67 +++++++++++++++++++++++++++++++++++++++++++-----------------
> 2 files changed, 50 insertions(+), 20 deletions(-)
>
> diff --git a/src/cl_api.c b/src/cl_api.c
> index cd4020e..25e621a 100644
> --- a/src/cl_api.c
> +++ b/src/cl_api.c
> @@ -549,8 +549,9 @@ clCreateImage(cl_context context,
> goto error;
> }
> /* buffer refers to a valid buffer memory object if image_type is
> - CL_MEM_OBJECT_IMAGE1D_BUFFER. Otherwise it must be NULL. */
> + CL_MEM_OBJECT_IMAGE1D_BUFFER or CL_MEM_OBJECT_IMAGE2D. Otherwise it must be NULL. */
> if (image_desc->image_type != CL_MEM_OBJECT_IMAGE1D_BUFFER &&
> + image_desc->image_type != CL_MEM_OBJECT_IMAGE2D &&
> image_desc->buffer) {
> err = CL_INVALID_IMAGE_DESCRIPTOR;
> goto error;
> diff --git a/src/cl_mem.c b/src/cl_mem.c
> index b41ec14..3c5667e 100644
> --- a/src/cl_mem.c
> +++ b/src/cl_mem.c
> @@ -971,26 +971,47 @@ _cl_mem_new_image_from_buffer(cl_context ctx,
> if (UNLIKELY((err = cl_image_byte_per_pixel(image_format, &bpp)) != CL_SUCCESS))
> goto error;
>
> - // Per bspec, a image should has a at least 2 line vertical alignment,
> - // thus we can't simply attach a buffer to a 1d image surface which has the same size.
> - // We have to create a new image, and copy the buffer data to this new image.
> - // And replace all the buffer object's reference to this image.
> - image = _cl_mem_new_image(ctx, flags, image_format, image_desc->image_type,
> + if(image_desc->image_type == CL_MEM_OBJECT_IMAGE2D) {
Spec says:
The restrictions are:
all the values specified in image_desc except for mem_object must match
the image descriptor information associated with mem_object.
the channel data type specified in image_format must match the channel
data type associated with mem_object.
So I think here we may need to add some check.
> + image = _cl_mem_new_image(ctx, flags, image_format, image_desc->image_type,
> + image_desc->image_width, image_desc->image_height, image_desc->image_depth,
> + image_desc->image_row_pitch, image_desc->image_slice_pitch,
> + image_desc->buffer, errcode_ret);
~~~~~~~~~~~~~~~ here, why
image_desc->buffer?
> + } else if (image_desc->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER) {
> + // Per bspec, a image should has a at least 2 line vertical alignment,
> + // thus we can't simply attach a buffer to a 1d image surface which has the same size.
> + // We have to create a new image, and copy the buffer data to this new image.
> + // And replace all the buffer object's reference to this image.
> + image = _cl_mem_new_image(ctx, flags, image_format, image_desc->image_type,
> mem_buffer->base.size / bpp, 0, 0, 0, 0, NULL, errcode_ret);
> + }
> + else
> + assert(0);
> +
> if (image == NULL)
> return NULL;
> - void *src = cl_mem_map(buffer, 0);
> - void *dst = cl_mem_map(image, 1);
> - //
> - // FIXME, we could use copy buffer to image to do this on GPU latter.
> - // currently the copy buffer to image function doesn't support 1D image.
> - //
> - // There is a potential risk that this buffer was mapped and the caller
> - // still hold the pointer and want to access it again. This scenario is
> - // not explicitly forbidden in the spec, although it should not be permitted.
> - memcpy(dst, src, mem_buffer->base.size);
> - cl_mem_unmap(buffer);
> - cl_mem_unmap(image);
> +
> + if(image_desc->image_type == CL_MEM_OBJECT_IMAGE2D)
> + {
> + size_t origin[] = {0,0,0};
> + size_t region[] = {image_desc->image_width, image_desc->image_height, 1};
> + clEnqueueCopyBufferToImage(ctx->queues, buffer, image, 0, origin, region, 0, NULL, NULL);
> + }
> + else if (image_desc->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER)
> + {
> + // FIXME, we could use copy buffer to image to do this on GPU latter.
> + // currently the copy buffer to image function doesn't support 1D image.
> + //
> + // There is a potential risk that this buffer was mapped and the caller
> + // still hold the pointer and want to access it again. This scenario is
> + // not explicitly forbidden in the spec, although it should not be permitted.
> + void *src = cl_mem_map(buffer, 0);
> + void *dst = cl_mem_map(image, 1);
> + memcpy(dst, src, mem_buffer->base.size);
> + cl_mem_unmap(image);
> + cl_mem_unmap(buffer);
> + }
> + else
> + assert(0);
>
> if (err != 0)
> goto error;
> @@ -1025,12 +1046,20 @@ cl_mem_new_image(cl_context context,
> {
> switch (image_desc->image_type) {
> case CL_MEM_OBJECT_IMAGE1D:
> - case CL_MEM_OBJECT_IMAGE2D:
> case CL_MEM_OBJECT_IMAGE3D:
> return _cl_mem_new_image(context, flags, image_format, image_desc->image_type,
> image_desc->image_width, image_desc->image_height, image_desc->image_depth,
> image_desc->image_row_pitch, image_desc->image_slice_pitch,
> host_ptr, errcode_ret);
> + case CL_MEM_OBJECT_IMAGE2D:
> + if(image_desc->buffer)
> + return _cl_mem_new_image_from_buffer(context, flags, image_format,
> + image_desc, errcode_ret);
> + else
> + return _cl_mem_new_image(context, flags, image_format, image_desc->image_type,
> + image_desc->image_width, image_desc->image_height, image_desc->image_depth,
> + image_desc->image_row_pitch, image_desc->image_slice_pitch,
> + host_ptr, errcode_ret);
> case CL_MEM_OBJECT_IMAGE1D_ARRAY:
> case CL_MEM_OBJECT_IMAGE2D_ARRAY:
> return _cl_mem_new_image(context, flags, image_format, image_desc->image_type,
> @@ -1065,7 +1094,7 @@ cl_mem_delete(cl_mem mem)
> /* iff we are a image, delete the 1d buffer if has. */
> if (IS_IMAGE(mem)) {
> if (cl_mem_image(mem)->buffer_1d) {
> - assert(cl_mem_image(mem)->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER);
> + assert(cl_mem_image(mem)->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER ||cl_mem_image(mem)->image_type == CL_MEM_OBJECT_IMAGE2D);
> cl_mem_delete(cl_mem_image(mem)->buffer_1d);
> cl_mem_image(mem)->buffer_1d = NULL;
> }
More information about the Beignet
mailing list