summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChuanbo Weng <chuanbo.weng@intel.com>2015-11-06 15:57:50 +0800
committerYang Rong <rong.r.yang@intel.com>2015-11-10 10:52:10 +0800
commit069a27813532110a2b126566ac227eb76e664315 (patch)
tree9f020a5cb9b9908887f8b462c654e34d537ada08 /src
parent323e2f2eb1e2589b8bc1fc0ac0bde8debc11d27b (diff)
Add extension clCreateImageFromFdINTEL to create cl image by external fd.
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@intel.com> Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/cl_api.c38
-rw-r--r--src/cl_driver.h3
-rw-r--r--src/cl_driver_defs.c1
-rw-r--r--src/cl_mem.c58
-rw-r--r--src/cl_mem.h8
-rw-r--r--src/intel/intel_driver.c17
6 files changed, 125 insertions, 0 deletions
diff --git a/src/cl_api.c b/src/cl_api.c
index 7a75ca3a..ec417d4e 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 13cd6ba2..19afb433 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 b3e8403d..d25fd5d1 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 6bbd27ab..9a6bb832 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 91c109b7..fb241151 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 a9c147a9..b3712e54 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());
}