[Beignet] [PATCH] Add extension clCreateMemObjectFromFdIntel to create cl memory object by external buffer object's fd.

Zhao Yakui yakui.zhao at intel.com
Thu Sep 17 19:58:28 PDT 2015


On 09/18/2015 10:39 AM, Chuanbo Weng wrote:
> Before this patch, Beignet can only import external bo by its
> handle using clCreateBufferFromLibvaIntel/clCreateImageFromLibvaIntel.
> Render node is the first choice of access gpu in currect Beignet
> implementation, it causes DRM_IOCTL_GEM_OPEN fail. So it's necessary to
> add this extension to support buffer sharing between different
> libraries.

The Fd is not restricted to Intel GFX object.
Can we rename it as clCreateBufferFromPrimeFD/clCreateImageFromPrimeFD?
Otherwise it will cause the confusion that FD only can come from Intel 
GFX object.

>
> Signed-off-by: Chuanbo Weng<chuanbo.weng at intel.com>
> ---
>   include/CL/cl_intel.h    | 24 +++++++++++++
>   src/cl_api.c             | 42 +++++++++++++++++++++++
>   src/cl_driver.h          |  6 ++++
>   src/cl_driver_defs.c     |  2 ++
>   src/cl_mem.c             | 88 ++++++++++++++++++++++++++++++++++++++++++++++++
>   src/cl_mem.h             | 13 +++++++
>   src/intel/intel_driver.c | 51 ++++++++++++++++++++++++++--
>   7 files changed, 223 insertions(+), 3 deletions(-)
>
> diff --git a/include/CL/cl_intel.h b/include/CL/cl_intel.h
> index 28bcb62..50262cb 100644
> --- a/include/CL/cl_intel.h
> +++ b/include/CL/cl_intel.h
> @@ -133,6 +133,30 @@ typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetMemObjectFdIntel_fn)(
>                                cl_mem       /* Memory Obejct */,
>                                int*         /* returned fd */);
>
> +/* Create memory object from external buffer object by fd */
> +typedef struct _cl_mem_object_desc {
> +    int                     fd;
> +    cl_mem_object_type      type;
> +    int                     size;
> +    struct {
> +      cl_image_format         fmt;
> +      uint32_t                offset;
> +      uint32_t                width;
> +      uint32_t                height;
> +      uint32_t                row_pitch;
> +    } image_info;
> +} cl_mem_object_desc;
> +
> +extern CL_API_ENTRY cl_mem CL_API_CALL
> +clCreateMemObjectFromFdIntel(cl_context                   /* context */,
> +                             const cl_mem_object_desc *   /* desc */,
> +                             cl_int *                     /* errcode_ret */);
> +
> +typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateMemObjectFromFdIntel_fn)(
> +                             cl_context                   /* context */,
> +                             const cl_mem_object_desc *   /* desc */,
> +                             cl_int *                     /* errcode_ret */);
> +
>   #ifdef __cplusplus
>   }
>   #endif
> diff --git a/src/cl_api.c b/src/cl_api.c
> index dbbcbb0..b879a12 100644
> --- a/src/cl_api.c
> +++ b/src/cl_api.c
> @@ -3187,6 +3187,7 @@ internal_clGetExtensionFunctionAddress(const char *func_name)
>     EXTFUNC(clCreateBufferFromLibvaIntel)
>     EXTFUNC(clCreateImageFromLibvaIntel)
>     EXTFUNC(clGetMemObjectFdIntel)
> +  EXTFUNC(clCreateMemObjectFromFdIntel)
>     return NULL;
>   }
>
> @@ -3355,3 +3356,44 @@ clGetMemObjectFdIntel(cl_context context,
>   error:
>     return err;
>   }
> +
> +cl_mem
> +clCreateMemObjectFromFdIntel(cl_context context,
> +                             const cl_mem_object_desc* desc,
> +                             cl_int *errorcode_ret)
> +{
> +  cl_mem mem = NULL;
> +  cl_int err = CL_SUCCESS;
> +  CHECK_CONTEXT (context);
> +
> +  if (!desc) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +
> +  //create buffer object
> +  if(desc->type == CL_MEM_OBJECT_BUFFER){
> +    mem = cl_mem_new_buffer_from_fd(context, desc->fd, desc->size,&err);
> +  }
> +  /* Create image object from fd.
> +   * We just support creating CL_MEM_OBJECT_IMAGE2D image object now.
> +   * Other image type will be supported later if necessary.
> +   */
> +  else if(desc->type == CL_MEM_OBJECT_IMAGE2D){
> +    mem = cl_mem_new_image_from_fd(context,
> +                                   desc->fd, desc->size,
> +                                   desc->image_info.offset,
> +                                   desc->image_info.width, desc->image_info.height,
> +                                   desc->image_info.fmt, desc->image_info.row_pitch,
> +&err);
> +  }
> +  else{
> +    err = CL_INVALID_ARG_VALUE;
> +    goto error;
> +  }
> +
> +error:
> +  if (errorcode_ret)
> +    *errorcode_ret = err;
> +  return mem;
> +}
> diff --git a/src/cl_driver.h b/src/cl_driver.h
> index 1ab4dff..369c24c 100644
> --- a/src/cl_driver.h
> +++ b/src/cl_driver.h
> @@ -381,6 +381,12 @@ extern cl_buffer_get_fd_cb *cl_buffer_get_fd;
>   typedef int (cl_buffer_get_tiling_align_cb)(cl_context ctx, uint32_t tiling_mode, uint32_t dim);
>   extern cl_buffer_get_tiling_align_cb *cl_buffer_get_tiling_align;
>
> +typedef cl_buffer (cl_buffer_get_buffer_from_fd_cb)(cl_context ctx, int fd, int size);
> +extern cl_buffer_get_buffer_from_fd_cb *cl_buffer_get_buffer_from_fd;
> +
> +typedef cl_buffer (cl_buffer_get_image_from_fd_cb)(cl_context ctx, int fd, int size, struct _cl_mem_image *image);
> +extern cl_buffer_get_image_from_fd_cb *cl_buffer_get_image_from_fd;
> +
>   /* Get the device id */
>   typedef int (cl_driver_get_device_id_cb)(void);
>   extern cl_driver_get_device_id_cb *cl_driver_get_device_id;
> diff --git a/src/cl_driver_defs.c b/src/cl_driver_defs.c
> index b77acdc..d25fd5d 100644
> --- a/src/cl_driver_defs.c
> +++ b/src/cl_driver_defs.c
> @@ -53,6 +53,8 @@ LOCAL cl_buffer_get_buffer_from_libva_cb *cl_buffer_get_buffer_from_libva = NULL
>   LOCAL cl_buffer_get_image_from_libva_cb *cl_buffer_get_image_from_libva = NULL;
>   LOCAL cl_buffer_get_fd_cb *cl_buffer_get_fd = NULL;
>   LOCAL cl_buffer_get_tiling_align_cb *cl_buffer_get_tiling_align = NULL;
> +LOCAL cl_buffer_get_buffer_from_fd_cb *cl_buffer_get_buffer_from_fd = NULL;
> +LOCAL cl_buffer_get_image_from_fd_cb *cl_buffer_get_image_from_fd = NULL;
>
>   /* cl_khr_gl_sharing */
>   LOCAL cl_gl_acquire_texture_cb *cl_gl_acquire_texture = NULL;
> diff --git a/src/cl_mem.c b/src/cl_mem.c
> index b5671bd..420bb78 100644
> --- a/src/cl_mem.c
> +++ b/src/cl_mem.c
> @@ -2097,3 +2097,91 @@ cl_mem_get_fd(cl_mem mem,
>   	err = CL_INVALID_OPERATION;
>     return err;
>   }
> +
> +LOCAL cl_mem cl_mem_new_buffer_from_fd(cl_context ctx,
> +                                       int fd,
> +                                       int buffer_sz,
> +                                       cl_int* errcode)
> +{
> +  cl_int err = CL_SUCCESS;
> +  cl_mem mem = NULL;
> +
> +  mem = cl_mem_allocate(CL_MEM_BUFFER_TYPE, ctx, 0, 0, CL_FALSE, NULL,&err);
> +  if (mem == NULL || err != CL_SUCCESS)
> +    goto error;
> +
> +  mem->bo = cl_buffer_get_buffer_from_fd(ctx, fd, buffer_sz);
> +  if (mem->bo == NULL) {
> +    err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
> +    goto error;
> +  }
> +  mem->size = buffer_sz;
> +
> +exit:
> +  if (errcode)
> +    *errcode = err;
> +  return mem;
> +
> +error:
> +  cl_mem_delete(mem);
> +  mem = NULL;
> +  goto exit;
> +}
> +
> +LOCAL cl_mem cl_mem_new_image_from_fd(cl_context ctx,
> +                                      int fd, int image_sz,
> +                                      size_t offset,
> +                                      size_t width, size_t height,
> +                                      cl_image_format fmt,
> +                                      size_t row_pitch,
> +                                      cl_int *errcode)
> +{
> +  cl_int err = CL_SUCCESS;
> +  cl_mem mem = NULL;
> +  struct _cl_mem_image *image = NULL;
> +  uint32_t intel_fmt, bpp;
> +
> +  /* Get the size of each pixel */
> +  if (UNLIKELY((err = cl_image_byte_per_pixel(&fmt,&bpp)) != CL_SUCCESS))
> +    goto error;
> +
> +  intel_fmt = cl_image_get_intel_format(&fmt);
> +  if (intel_fmt == INTEL_UNSUPPORTED_FORMAT) {
> +    err = CL_IMAGE_FORMAT_NOT_SUPPORTED;
> +    goto error;
> +  }
> +
> +  mem = cl_mem_allocate(CL_MEM_IMAGE_TYPE, ctx, 0, 0, 0, NULL,&err);
> +  if (mem == NULL || err != CL_SUCCESS) {
> +    err = CL_OUT_OF_HOST_MEMORY;
> +    goto error;
> +  }
> +
> +  image = cl_mem_image(mem);
> +
> +  mem->bo = cl_buffer_get_image_from_fd(ctx, fd, image_sz, image);
> +
> +  image->w = width;
> +  image->h = height;
> +  image->image_type = CL_MEM_OBJECT_IMAGE2D;
> +  image->depth = 2;
> +  image->fmt = fmt;
> +  image->intel_fmt = intel_fmt;
> +  image->bpp = bpp;
> +  image->row_pitch = row_pitch;
> +  image->slice_pitch = 0;
> +  // NOTE: tiling of image is set in cl_buffer_get_image_from_fd().
> +  image->tile_x = 0;
> +  image->tile_y = 0;
> +  image->offset = offset;
> +
> +exit:
> +  if (errcode)
> +    *errcode = err;
> +  return mem;
> +
> +error:
> +  cl_mem_delete(mem);
> +  mem = NULL;
> +  goto exit;
> +}
> diff --git a/src/cl_mem.h b/src/cl_mem.h
> index e027f15..739f107 100644
> --- a/src/cl_mem.h
> +++ b/src/cl_mem.h
> @@ -293,8 +293,21 @@ extern cl_mem cl_mem_new_libva_image(cl_context ctx,
>                                        cl_image_format fmt,
>                                        size_t row_pitch,
>                                        cl_int *errcode);
> +
>   extern cl_int cl_mem_get_fd(cl_mem mem, int* fd);
>
> +extern cl_mem cl_mem_new_buffer_from_fd(cl_context ctx,
> +                                        int fd,
> +                                        int buffer_sz,
> +                                        cl_int* errcode);
> +
> +extern cl_mem cl_mem_new_image_from_fd(cl_context ctx,
> +                                       int fd, int image_sz,
> +                                       size_t offset,
> +                                       size_t width, size_t height,
> +                                       cl_image_format fmt,
> +                                       size_t row_pitch,
> +                                       cl_int *errcode);
>
>   #endif /* __CL_MEM_H__ */
>
> diff --git a/src/intel/intel_driver.c b/src/intel/intel_driver.c
> index 507c910..d19f721 100644
> --- a/src/intel/intel_driver.c
> +++ b/src/intel/intel_driver.c
> @@ -369,7 +369,7 @@ intel_driver_unlock_hardware(intel_driver_t *driver)
>   }
>
>   LOCAL dri_bo*
> -intel_driver_share_buffer(intel_driver_t *driver, const char *sname, uint32_t name)
> +intel_driver_share_buffer_from_name(intel_driver_t *driver, const char *sname, uint32_t name)
>   {
>     dri_bo *bo = intel_bo_gem_create_from_name(driver->bufmgr,
>                                                sname,
> @@ -381,6 +381,19 @@ intel_driver_share_buffer(intel_driver_t *driver, const char *sname, uint32_t na
>     return bo;
>   }
>
> +LOCAL dri_bo*
> +intel_driver_share_buffer_from_fd(intel_driver_t *driver, int fd, int size)
> +{
> +  dri_bo *bo = drm_intel_bo_gem_create_from_prime(driver->bufmgr,
> +                                                  fd,
> +                                                  size);
> +  if (bo == NULL) {
> +    fprintf(stderr, "drm_intel_bo_gem_create_from_prime create bo(size %d) from fd %d failed: %s\n", fd, size, strerror(errno));
> +    return NULL;
> +  }
> +  return bo;
> +}
> +
>   LOCAL uint32_t
>   intel_driver_shared_name(intel_driver_t *driver, dri_bo *bo)
>   {
> @@ -695,7 +708,7 @@ cl_buffer intel_share_buffer_from_libva(cl_context ctx,
>   {
>     drm_intel_bo *intel_bo;
>
> -  intel_bo = intel_driver_share_buffer((intel_driver_t *)ctx->drv, "shared from libva", bo_name);
> +  intel_bo = intel_driver_share_buffer_from_name((intel_driver_t *)ctx->drv, "shared from libva", bo_name);
>
>     if (intel_bo == NULL)
>       return NULL;
> @@ -713,7 +726,37 @@ cl_buffer intel_share_image_from_libva(cl_context ctx,
>     drm_intel_bo *intel_bo;
>     uint32_t intel_tiling, intel_swizzle_mode;
>
> -  intel_bo = intel_driver_share_buffer((intel_driver_t *)ctx->drv, "shared from libva", bo_name);
> +  intel_bo = intel_driver_share_buffer_from_name((intel_driver_t *)ctx->drv, "shared from libva", bo_name);
> +
> +  drm_intel_bo_get_tiling(intel_bo,&intel_tiling,&intel_swizzle_mode);
> +  image->tiling = get_cl_tiling(intel_tiling);
> +
> +  return (cl_buffer)intel_bo;
> +}
> +
> +cl_buffer intel_share_buffer_from_fd(cl_context ctx,
> +                                     int fd,
> +                                     int buffer_size)
> +{
> +  drm_intel_bo *intel_bo;
> +
> +  intel_bo = intel_driver_share_buffer_from_fd((intel_driver_t *)ctx->drv, fd, buffer_size);
> +
> +  if (intel_bo == NULL)
> +    return NULL;
> +
> +  return (cl_buffer)intel_bo;
> +}
> +
> +cl_buffer intel_share_image_from_fd(cl_context ctx,
> +                                    int fd,
> +                                    int image_size,
> +                                    struct _cl_mem_image *image)
> +{
> +  drm_intel_bo *intel_bo;
> +  uint32_t intel_tiling, intel_swizzle_mode;
> +
> +  intel_bo = intel_driver_share_buffer_from_fd((intel_driver_t *)ctx->drv, fd, image_size);
>
>     drm_intel_bo_get_tiling(intel_bo,&intel_tiling,&intel_swizzle_mode);
>     image->tiling = get_cl_tiling(intel_tiling);
> @@ -870,5 +913,7 @@ intel_setup_callbacks(void)
>     cl_buffer_wait_rendering = (cl_buffer_wait_rendering_cb *) drm_intel_bo_wait_rendering;
>     cl_buffer_get_fd = (cl_buffer_get_fd_cb *) drm_intel_bo_gem_export_to_prime;
>     cl_buffer_get_tiling_align = (cl_buffer_get_tiling_align_cb *)intel_buffer_get_tiling_align;
> +  cl_buffer_get_buffer_from_fd = (cl_buffer_get_buffer_from_fd_cb *) intel_share_buffer_from_fd;
> +  cl_buffer_get_image_from_fd = (cl_buffer_get_image_from_fd_cb *) intel_share_image_from_fd;
>     intel_set_gpgpu_callbacks(intel_get_device_id());
>   }



More information about the Beignet mailing list