[Beignet] [PATCH 1/2] [opencl-1.2] Add the support for 1D image from buffer.

Zhigang Gong zhigang.gong at linux.intel.com
Thu May 22 23:10:08 PDT 2014


LGTM, will push latter. Thanks.

On Fri, May 16, 2014 at 02:52:46PM +0800, junyan.he at inbox.com wrote:
> From: Junyan He <junyan.he at linux.intel.com>
> 
> Signed-off-by: Junyan He <junyan.he at linux.intel.com>
> ---
>  backend/src/ocl_stdlib.tmpl.h |   1 +
>  src/cl_device_id.c            |   1 +
>  src/cl_device_id.h            |   1 +
>  src/cl_gt_device.h            |   1 +
>  src/cl_mem.c                  | 148 +++++++++++++++++++++++++++++++++++++++++-
>  src/cl_mem.h                  |   1 +
>  src/intel/intel_gpgpu.c       |   3 +-
>  7 files changed, 154 insertions(+), 2 deletions(-)
> 
> diff --git a/backend/src/ocl_stdlib.tmpl.h b/backend/src/ocl_stdlib.tmpl.h
> index 8ab8b31..83a5b5b 100755
> --- a/backend/src/ocl_stdlib.tmpl.h
> +++ b/backend/src/ocl_stdlib.tmpl.h
> @@ -92,6 +92,7 @@ typedef __texture struct _image3d_t* __image3d_t;
>  typedef const ushort __sampler_t;
>  typedef size_t __event_t;
>  #define image1d_t __image1d_t
> +#define image1d_buffer_t __image1d_t
>  #define image2d_t __image2d_t
>  #define image3d_t __image3d_t
>  #define sampler_t __sampler_t
> diff --git a/src/cl_device_id.c b/src/cl_device_id.c
> index 2b443c6..f60ad51 100644
> --- a/src/cl_device_id.c
> +++ b/src/cl_device_id.c
> @@ -327,6 +327,7 @@ cl_get_device_info(cl_device_id     device,
>      DECL_FIELD(GLOBAL_MEM_CACHE_SIZE, global_mem_cache_size)
>      DECL_FIELD(GLOBAL_MEM_SIZE, global_mem_size)
>      DECL_FIELD(MAX_CONSTANT_BUFFER_SIZE, max_constant_buffer_size)
> +    DECL_FIELD(IMAGE_MAX_BUFFER_SIZE, image_mem_size)
>      DECL_FIELD(MAX_CONSTANT_ARGS, max_constant_args)
>      DECL_FIELD(LOCAL_MEM_TYPE, local_mem_type)
>      DECL_FIELD(LOCAL_MEM_SIZE, local_mem_size)
> diff --git a/src/cl_device_id.h b/src/cl_device_id.h
> index 5f7c9fe..2bbe98e 100644
> --- a/src/cl_device_id.h
> +++ b/src/cl_device_id.h
> @@ -55,6 +55,7 @@ struct _cl_device_id {
>    size_t   image3d_max_width;
>    size_t   image3d_max_height;
>    size_t   image3d_max_depth;
> +  cl_ulong image_mem_size;
>    cl_uint  max_samplers;
>    size_t   max_parameter_size;
>    cl_uint  mem_base_addr_align;
> diff --git a/src/cl_gt_device.h b/src/cl_gt_device.h
> index 110988a..327e2a9 100644
> --- a/src/cl_gt_device.h
> +++ b/src/cl_gt_device.h
> @@ -46,6 +46,7 @@
>  .image3d_max_width = 8192,
>  .image3d_max_height = 8192,
>  .image3d_max_depth = 2048,
> +.image_mem_size = 8192,
>  .max_samplers = 16,
>  .mem_base_addr_align = sizeof(cl_long) * 16 * 8,
>  .min_data_type_align_size = sizeof(cl_long) * 16,
> diff --git a/src/cl_mem.c b/src/cl_mem.c
> index 0250f0a..08e4f66 100644
> --- a/src/cl_mem.c
> +++ b/src/cl_mem.c
> @@ -151,10 +151,17 @@ cl_get_image_info(cl_mem mem,
>      FIELD_SIZE(IMAGE_WIDTH, size_t);
>      FIELD_SIZE(IMAGE_HEIGHT, size_t);
>      FIELD_SIZE(IMAGE_DEPTH, size_t);
> +    FIELD_SIZE(IMAGE_BUFFER, cl_mem);
>    default:
>      return CL_INVALID_VALUE;
>    }
>  
> +  /* Do some further check. */
> +  if (param_name == CL_IMAGE_BUFFER &&
> +     image->image_type != CL_MEM_OBJECT_IMAGE1D_BUFFER) {
> +     return CL_INVALID_VALUE;
> +  }
> +
>    switch(param_name)
>    {
>    case CL_IMAGE_FORMAT:
> @@ -178,6 +185,9 @@ cl_get_image_info(cl_mem mem,
>    case CL_IMAGE_DEPTH:
>      *(size_t *)param_value = image->depth;
>      break;
> +  case CL_IMAGE_BUFFER:
> +    *(cl_mem *)param_value = image->buffer_1d;
> +    break;
>    }
>  
>    return CL_SUCCESS;
> @@ -641,6 +651,131 @@ error:
>    goto exit;
>  }
>  
> +static cl_mem
> +_cl_mem_new_image_from_buffer(cl_context ctx,
> +                              cl_mem_flags flags,
> +                              const cl_image_format* image_format,
> +                              const cl_image_desc *image_desc,
> +                              cl_int *errcode_ret)
> +{
> +  cl_mem image = NULL;
> +  cl_mem buffer = image_desc->buffer;
> +  cl_int err = CL_SUCCESS;
> +  *errcode_ret = err;
> +  cl_ulong max_size;
> +  cl_mem_flags merged_flags;
> +  uint32_t bpp;
> +  uint32_t intel_fmt = INTEL_UNSUPPORTED_FORMAT;
> +  size_t offset = 0;
> +
> +  /* Get the size of each pixel */
> +  if (UNLIKELY((err = cl_image_byte_per_pixel(image_format, &bpp)) != CL_SUCCESS))
> +    goto error;
> +
> +  /* Only a sub-set of the formats are supported */
> +  intel_fmt = cl_image_get_intel_format(image_format);
> +  if (UNLIKELY(intel_fmt == INTEL_UNSUPPORTED_FORMAT)) {
> +    err = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
> +    goto error;
> +  }
> +
> +  if (!buffer) {
> +    err = CL_INVALID_IMAGE_DESCRIPTOR;
> +    goto error;
> +  }
> +
> +  if (flags & (CL_MEM_USE_HOST_PTR|CL_MEM_ALLOC_HOST_PTR|CL_MEM_COPY_HOST_PTR)) {
> +    err = CL_INVALID_IMAGE_DESCRIPTOR;
> +    goto error;
> +  }
> +
> +  /* access check. */
> +  if ((buffer->flags & CL_MEM_WRITE_ONLY) &&
> +      (flags & (CL_MEM_READ_WRITE|CL_MEM_READ_ONLY))) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +  if ((buffer->flags & CL_MEM_READ_ONLY) &&
> +      (flags & (CL_MEM_READ_WRITE|CL_MEM_WRITE_ONLY))) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +  if ((buffer->flags & CL_MEM_HOST_WRITE_ONLY) &&
> +      (flags & CL_MEM_HOST_READ_ONLY)) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +  if ((buffer->flags & CL_MEM_HOST_READ_ONLY) &&
> +      (flags & CL_MEM_HOST_WRITE_ONLY)) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +  if ((buffer->flags & CL_MEM_HOST_NO_ACCESS) &&
> +      (flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY))) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +
> +  if ((err = cl_get_device_info(ctx->device,
> +                                CL_DEVICE_IMAGE_MAX_BUFFER_SIZE,
> +                                sizeof(max_size),
> +                                &max_size,
> +                                NULL)) != CL_SUCCESS) {
> +    goto error;
> +  }
> +
> +  if (image_desc->image_width > max_size) {
> +    err = CL_INVALID_IMAGE_DESCRIPTOR;
> +    goto error;
> +  }
> +
> +  if (image_desc->image_width*bpp > buffer->size) {
> +    err = CL_INVALID_IMAGE_DESCRIPTOR;
> +    goto error;
> +  }
> +
> +  merged_flags = buffer->flags;
> +  if (flags & (CL_MEM_READ_WRITE|CL_MEM_READ_WRITE|CL_MEM_WRITE_ONLY)) {
> +    merged_flags &= ~(CL_MEM_READ_WRITE|CL_MEM_READ_WRITE|CL_MEM_WRITE_ONLY);
> +    merged_flags |= flags & (CL_MEM_READ_WRITE|CL_MEM_READ_WRITE|CL_MEM_WRITE_ONLY);
> +  }
> +  if (flags & (CL_MEM_HOST_WRITE_ONLY|CL_MEM_HOST_READ_ONLY|CL_MEM_HOST_NO_ACCESS)) {
> +    merged_flags &= ~(CL_MEM_HOST_WRITE_ONLY|CL_MEM_HOST_READ_ONLY|CL_MEM_HOST_NO_ACCESS);
> +    merged_flags |= flags & (CL_MEM_HOST_WRITE_ONLY|CL_MEM_HOST_READ_ONLY|CL_MEM_HOST_NO_ACCESS);
> +  }
> +
> +  /* Because the buffer is NO_TILING, the image should be no tiling. */
> +  image = cl_mem_allocate(CL_MEM_IMAGE_TYPE, ctx, flags, merged_flags, CL_FALSE, &err);
> +  if (image == NULL || err != CL_SUCCESS)
> +    goto error;
> +
> +  cl_buffer_reference(buffer->bo);
> +  image->bo = buffer->bo;
> +  image->size = buffer->size;
> +  /* If it is a sub buffer, we need to start from the sub offset. */
> +  if (buffer->type == CL_MEM_SUBBUFFER_TYPE) {
> +    offset = ((struct _cl_mem_buffer *)buffer)->sub_offset;
> +  }
> +  if (image->flags & CL_MEM_USE_HOST_PTR) {
> +    /* Now point to the right offset if buffer is a SUB_BUFFER. */
> +    image->host_ptr = buffer->host_ptr + offset;
> +  }
> +
> +  cl_mem_image_init(cl_mem_image(image), image_desc->image_width, 1, image_desc->image_type,
> +                    1, *image_format, intel_fmt, bpp, image_desc->image_width*bpp, 0, CL_NO_TILE,
> +                    0, 0, offset);
> +  cl_mem_add_ref(buffer);
> +  cl_mem_image(image)->buffer_1d = buffer;
> +  return image;
> +
> +error:
> +  if (image)
> +    cl_mem_delete(image);
> +  image = NULL;
> +  *errcode_ret = err;
> +  return image;
> +}
> +
>  LOCAL cl_mem
>  cl_mem_new_image(cl_context context,
>                   cl_mem_flags flags,
> @@ -659,8 +794,10 @@ cl_mem_new_image(cl_context context,
>                               host_ptr, errcode_ret);
>    case CL_MEM_OBJECT_IMAGE2D_ARRAY:
>    case CL_MEM_OBJECT_IMAGE1D_ARRAY:
> -  case CL_MEM_OBJECT_IMAGE1D_BUFFER:
>      NOT_IMPLEMENTED;
> +  case CL_MEM_OBJECT_IMAGE1D_BUFFER:
> +    return _cl_mem_new_image_from_buffer(context, flags, image_format,
> +                                         image_desc, errcode_ret);
>      break;
>    case CL_MEM_OBJECT_BUFFER:
>    default:
> @@ -683,6 +820,15 @@ cl_mem_delete(cl_mem mem)
>    }
>  #endif
>  
> +  /* 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);
> +      cl_mem_delete(cl_mem_image(mem)->buffer_1d);
> +      cl_mem_image(mem)->buffer_1d = NULL;
> +    }
> +  }
> +
>    /* Remove it from the list */
>    assert(mem->ctx);
>    pthread_mutex_lock(&mem->ctx->buffer_lock);
> diff --git a/src/cl_mem.h b/src/cl_mem.h
> index afa48fe..a3dcdc6 100644
> --- a/src/cl_mem.h
> +++ b/src/cl_mem.h
> @@ -83,6 +83,7 @@ struct _cl_mem_image {
>    cl_image_tiling_t tiling;       /* only IVB+ supports TILE_[X,Y] (image only) */
>    size_t tile_x, tile_y;          /* tile offset, used for mipmap images.  */
>    size_t offset;                  /* offset for dri_bo, used when it's reloc. */
> +  cl_mem buffer_1d;               /* if the image is created from buffer, it point to the buffer.*/
>  };
>  
>  struct _cl_mem_gl_image {
> diff --git a/src/intel/intel_gpgpu.c b/src/intel/intel_gpgpu.c
> index 014b95f..7a24854 100644
> --- a/src/intel/intel_gpgpu.c
> +++ b/src/intel/intel_gpgpu.c
> @@ -570,10 +570,11 @@ static int
>  intel_get_surface_type(cl_mem_object_type type)
>  {
>    switch (type) {
> +  case CL_MEM_OBJECT_IMAGE1D_BUFFER:
>    case CL_MEM_OBJECT_IMAGE1D: return I965_SURFACE_1D;
> +
>    case CL_MEM_OBJECT_IMAGE2D: return I965_SURFACE_2D;
>    case CL_MEM_OBJECT_IMAGE3D: return I965_SURFACE_3D;
> -  case CL_MEM_OBJECT_IMAGE1D_BUFFER:
>    case CL_MEM_OBJECT_IMAGE2D_ARRAY:
>    case CL_MEM_OBJECT_IMAGE1D_ARRAY:
>      NOT_IMPLEMENTED;
> -- 
> 1.8.3.2
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list