[Beignet] [PATCH v3 2/2] Add extension clCreateImageFromFdINTEL to create cl image by external fd.

Chuanbo Weng chuanbo.weng at intel.com
Thu Nov 5 23:57:50 PST 2015


Before this patch, Beignet can only create cl image from external bo by
its handle using clCreateImageFromLibvaIntel. Render node is the first
choice of accessing gpu in currect Beignet implementation. DRM_IOCTL_GEM_OPEN
is used by clCreateBufferFromLibvaIntel but forbidden in Render node mode.
So it's necessary to add this extension to support buffer sharing between
different libraries.

v2:
Seperate clCreateMemObjectFromFdIntel into two extensions: clCreateBufferFromFdINTEL
and clCreateImageFromFdINTEL.

v3:
Set depth of _cl_mem_image to 0 because it's CL_MEM_OBJECT_IMAGE2D type.
Fix rebase conflict: add a parameter when invoke cl_mem_allocate.

Signed-off-by: Chuanbo Weng <chuanbo.weng at intel.com>
---
 include/CL/cl_intel.h    | 21 ++++++++++++++++++
 src/cl_api.c             | 38 +++++++++++++++++++++++++++++++
 src/cl_driver.h          |  3 +++
 src/cl_driver_defs.c     |  1 +
 src/cl_mem.c             | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/cl_mem.h             |  8 +++++++
 src/intel/intel_driver.c | 17 ++++++++++++++
 7 files changed, 146 insertions(+)

diff --git a/include/CL/cl_intel.h b/include/CL/cl_intel.h
index 01da553..0ea4af4 100644
--- a/include/CL/cl_intel.h
+++ b/include/CL/cl_intel.h
@@ -138,6 +138,17 @@ typedef struct _cl_import_buffer_info_intel {
     int                     size;
 } cl_import_buffer_info_intel;
 
+typedef struct _cl_import_image_info_intel {
+    int                     fd;
+    int                     size;
+    cl_mem_object_type      type;
+    cl_image_format         fmt;
+    uint32_t                offset;
+    uint32_t                width;
+    uint32_t                height;
+    uint32_t                row_pitch;
+} cl_import_image_info_intel;
+
 /* Create memory object from external buffer object by fd */
 extern CL_API_ENTRY cl_mem CL_API_CALL
 clCreateBufferFromFdINTEL(cl_context                            /* context */,
@@ -149,6 +160,16 @@ typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateBufferFromFdINTEL_fn)(
                              const cl_import_buffer_info_intel *   /* info */,
                              cl_int *                              /* errcode_ret */);
 
+extern CL_API_ENTRY cl_mem CL_API_CALL
+clCreateImageFromFdINTEL(cl_context                            /* context */,
+                         const cl_import_image_info_intel *    /* info */,
+                         cl_int *                              /* errcode_ret */);
+
+typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateImageFromFdINTEL_fn)(
+                             cl_context                            /* context */,
+                             const cl_import_image_info_intel *    /* info */,
+                             cl_int *                              /* errcode_ret */);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/cl_api.c b/src/cl_api.c
index 7a75ca3..ec417d4 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -3191,6 +3191,7 @@ internal_clGetExtensionFunctionAddress(const char *func_name)
   EXTFUNC(clCreateImageFromLibvaIntel)
   EXTFUNC(clGetMemObjectFdIntel)
   EXTFUNC(clCreateBufferFromFdINTEL)
+  EXTFUNC(clCreateImageFromFdINTEL)
   return NULL;
 }
 
@@ -3381,3 +3382,40 @@ error:
     *errorcode_ret = err;
   return mem;
 }
+
+cl_mem
+clCreateImageFromFdINTEL(cl_context context,
+                         const cl_import_image_info_intel* info,
+                         cl_int *errorcode_ret)
+{
+  cl_mem mem = NULL;
+  cl_int err = CL_SUCCESS;
+  CHECK_CONTEXT (context);
+
+  if (!info) {
+    err = CL_INVALID_VALUE;
+    goto error;
+  }
+
+  /* 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.
+   */
+  if(info->type == CL_MEM_OBJECT_IMAGE2D){
+    mem = cl_mem_new_image_from_fd(context,
+                                   info->fd, info->size,
+                                   info->offset,
+                                   info->width, info->height,
+                                   info->fmt, 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 13cd6ba..19afb43 100644
--- a/src/cl_driver.h
+++ b/src/cl_driver.h
@@ -384,6 +384,9 @@ 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 b3e8403..d25fd5d 100644
--- a/src/cl_driver_defs.c
+++ b/src/cl_driver_defs.c
@@ -54,6 +54,7 @@ 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 6bbd27a..9a6bb83 100644
--- a/src/cl_mem.c
+++ b/src/cl_mem.c
@@ -2236,3 +2236,61 @@ error:
   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, 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 = 0;
+  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 91c109b..fb24115 100644
--- a/src/cl_mem.h
+++ b/src/cl_mem.h
@@ -303,5 +303,13 @@ extern cl_mem cl_mem_new_buffer_from_fd(cl_context ctx,
                                         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 a9c147a..b3712e5 100644
--- a/src/intel/intel_driver.c
+++ b/src/intel/intel_driver.c
@@ -750,6 +750,22 @@ cl_buffer intel_share_buffer_from_fd(cl_context ctx,
   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);
+
+  return (cl_buffer)intel_bo;
+}
+
 static cl_buffer intel_buffer_alloc_userptr(cl_buffer_mgr bufmgr, const char* name, void *data,size_t size, unsigned long flags)
 {
 #ifdef HAS_USERPTR
@@ -905,5 +921,6 @@ intel_setup_callbacks(void)
   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());
 }
-- 
1.9.1



More information about the Beignet mailing list