[Beignet] [PATCH] Add extension clCreateMemObjectFromFdIntel to create cl memory object by external buffer object's fd.
Chuanbo Weng
chuanbo.weng at intel.com
Thu Sep 17 19:39:07 PDT 2015
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.
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());
}
--
1.9.1
More information about the Beignet
mailing list