[Beignet] [PATCH v2 2/2] add clCreateImageFromLibvaIntel() api

Lu Guanqun guanqun.lu at intel.com
Wed Oct 16 00:57:54 PDT 2013


We can pass in libva's buffer object with other info and then create an image
in our CL code.

Signed-off-by: Lu Guanqun <guanqun.lu at intel.com>
---
 include/CL/cl_intel.h    |   22 ++++++++++++++++++
 src/cl_api.c             |   26 ++++++++++++++++++++++
 src/cl_command_queue.c   |    2 +-
 src/cl_driver.h          |    4 +++
 src/cl_driver_defs.c     |    1 +
 src/cl_mem.c             |   55 ++++++++++++++++++++++++++++++++++++++++++++++
 src/cl_mem.h             |    9 +++++++-
 src/intel/intel_driver.c |   22 ++++++++++++++++--
 src/intel/intel_gpgpu.c  |   10 +++++---
 9 files changed, 142 insertions(+), 9 deletions(-)

diff --git a/include/CL/cl_intel.h b/include/CL/cl_intel.h
index d0cb492..3dd6055 100644
--- a/include/CL/cl_intel.h
+++ b/include/CL/cl_intel.h
@@ -101,6 +101,28 @@ typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateBufferFromLibvaIntel_fn)(
                              unsigned int   /* bo_name */,
                              cl_int *       /* errcode_ret */);
 
+/* Create image from libva's buffer object */
+typedef struct _cl_libva_image {
+    unsigned int            bo_name;
+    uint32_t                offset;
+    uint32_t                width;
+    uint32_t                height;
+    cl_image_format         fmt;
+    uint32_t                row_pitch;
+    uint32_t                slice_pitch;
+    uint32_t                reserved[8];
+} cl_libva_image;
+
+extern CL_API_ENTRY cl_mem CL_API_CALL
+clCreateImageFromLibvaIntel(cl_context               /* context */,
+                            const cl_libva_image *   /* info */,
+                            cl_int *                 /* errcode_ret */);
+
+typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateImageFromLibvaIntel_fn)(
+                             cl_context             /* context */,
+                             const cl_libva_image * /* info */,
+                             cl_int *               /* errcode_ret */);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/cl_api.c b/src/cl_api.c
index bf63eda..ec52e8b 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -2510,6 +2510,7 @@ clGetExtensionFunctionAddress(const char *func_name)
   EXTFUNC(clUnpinBufferIntel)
   EXTFUNC(clReportUnfreedIntel)
   EXTFUNC(clCreateBufferFromLibvaIntel)
+  EXTFUNC(clCreateImageFromLibvaIntel)
   return NULL;
 }
 
@@ -2624,3 +2625,28 @@ error:
   return mem;
 }
 
+cl_mem
+clCreateImageFromLibvaIntel(cl_context context,
+                            const cl_libva_image *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;
+  }
+
+  mem = cl_mem_new_libva_image(context,
+                               info->bo_name, info->offset, info->width, info->height,
+                               info->fmt, info->row_pitch, info->slice_pitch,
+                               &err);
+
+error:
+  if (errorcode_ret)
+    *errorcode_ret = err;
+  return mem;
+}
+
diff --git a/src/cl_command_queue.c b/src/cl_command_queue.c
index ff78770..13789f6 100644
--- a/src/cl_command_queue.c
+++ b/src/cl_command_queue.c
@@ -125,7 +125,7 @@ cl_command_queue_bind_image(cl_command_queue queue, cl_kernel k)
     assert(gbe_kernel_get_arg_type(k->opaque, id) == GBE_ARG_IMAGE);
     image = cl_mem_image(k->args[id].mem);
     set_image_info(k->curbe, &k->images[i], image);
-    cl_gpgpu_bind_image(queue->gpgpu, k->images[i].idx, image->base.bo,
+    cl_gpgpu_bind_image(queue->gpgpu, k->images[i].idx, image->base.bo, image->offset,
                         image->intel_fmt, image->image_type,
                         image->w, image->h, image->depth,
                         image->row_pitch, image->tiling);
diff --git a/src/cl_driver.h b/src/cl_driver.h
index 88dea58..a653587 100644
--- a/src/cl_driver.h
+++ b/src/cl_driver.h
@@ -110,6 +110,7 @@ extern cl_gpgpu_bind_sampler_cb *cl_gpgpu_bind_sampler;
 typedef void (cl_gpgpu_bind_image_cb)(cl_gpgpu state,
                                       uint32_t id,
                                       cl_buffer obj_bo,
+                                      uint32_t obj_bo_offset,
                                       uint32_t format,
                                       uint32_t type,
                                       int32_t w,
@@ -226,6 +227,9 @@ extern cl_buffer_release_from_texture_cb *cl_buffer_release_from_texture;
 typedef cl_buffer (cl_buffer_get_buffer_from_libva_cb)(cl_context ctx, unsigned int bo_name, size_t *sz);
 extern cl_buffer_get_buffer_from_libva_cb *cl_buffer_get_buffer_from_libva;
 
+typedef cl_buffer (cl_buffer_get_image_from_libva_cb)(cl_context ctx, unsigned int bo_name, struct _cl_mem_image *image);
+extern cl_buffer_get_image_from_libva_cb *cl_buffer_get_image_from_libva;
+
 /* Unref a buffer and destroy it if no more ref */
 typedef int (cl_buffer_unreference_cb)(cl_buffer);
 extern cl_buffer_unreference_cb *cl_buffer_unreference;
diff --git a/src/cl_driver_defs.c b/src/cl_driver_defs.c
index f67697e..2694a69 100644
--- a/src/cl_driver_defs.c
+++ b/src/cl_driver_defs.c
@@ -46,6 +46,7 @@ LOCAL cl_buffer_unpin_cb *cl_buffer_unpin = NULL;
 LOCAL cl_buffer_subdata_cb *cl_buffer_subdata = NULL;
 LOCAL cl_buffer_wait_rendering_cb *cl_buffer_wait_rendering = NULL;
 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;
 
 /* 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 e8a8f78..692bb70 100644
--- a/src/cl_mem.c
+++ b/src/cl_mem.c
@@ -1142,3 +1142,58 @@ error:
   mem = NULL;
   goto exit;
 }
+
+LOCAL cl_mem cl_mem_new_libva_image(cl_context ctx,
+                                    unsigned int bo_name, size_t offset,
+                                    size_t width, size_t height,
+                                    cl_image_format fmt,
+                                    size_t row_pitch, size_t slice_pitch,
+                                    cl_int *errcode)
+{
+  cl_int err = CL_SUCCESS;
+  cl_mem mem = NULL;
+  struct _cl_mem_image *image = NULL;
+  uint32_t intel_fmt, bpp;
+
+  intel_fmt = cl_image_get_intel_format(&fmt);
+  if (intel_fmt == INTEL_UNSUPPORTED_FORMAT) {
+    err = CL_IMAGE_FORMAT_NOT_SUPPORTED;
+    goto error;
+  }
+
+  cl_image_byte_per_pixel(&fmt, &bpp);
+
+  mem = cl_mem_allocate(CL_MEM_IMAGE_TYPE, ctx, 0, 0, 0, &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_libva(ctx, bo_name, 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 = slice_pitch;
+  // NOTE: tiling of image is set in cl_buffer_get_image_from_libva().
+  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 8e7259d..40318ac 100644
--- a/src/cl_mem.h
+++ b/src/cl_mem.h
@@ -100,7 +100,7 @@ struct _cl_mem_image {
   size_t host_row_pitch, host_slice_pitch;
   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;
+  size_t offset;                  /* offset for dri_bo, used when it's reloc. */
 };
 
 struct _cl_mem_gl_image {
@@ -252,5 +252,12 @@ extern cl_mem cl_mem_new_libva_buffer(cl_context ctx,
                                       unsigned int bo_name,
                                       cl_int *errcode);
 
+extern cl_mem cl_mem_new_libva_image(cl_context ctx,
+                                     unsigned int bo_name, size_t offset,
+                                     size_t width, size_t height,
+                                     cl_image_format fmt,
+                                     size_t row_pitch, size_t slice_pitch,
+                                     cl_int *errcode);
+
 #endif /* __CL_MEM_H__ */
 
diff --git a/src/intel/intel_driver.c b/src/intel/intel_driver.c
index dc194fe..9d6bbe8 100644
--- a/src/intel/intel_driver.c
+++ b/src/intel/intel_driver.c
@@ -405,9 +405,6 @@ intel_driver_get_ver(struct intel_driver *drv)
 static size_t drm_intel_bo_get_size(drm_intel_bo *bo) { return bo->size; }
 static void* drm_intel_bo_get_virtual(drm_intel_bo *bo) { return bo->virtual; }
 
-#if defined(HAS_EGL)
-#include "intel_dri_resource_sharing.h"
-#include "cl_image.h"
 static int get_cl_tiling(uint32_t drm_tiling)
 {
   switch(drm_tiling) {
@@ -420,6 +417,9 @@ static int get_cl_tiling(uint32_t drm_tiling)
   return CL_NO_TILE;
 }
 
+#if defined(HAS_EGL)
+#include "intel_dri_resource_sharing.h"
+#include "cl_image.h"
 static int cl_get_clformat_from_texture(GLint tex_format, cl_image_format * cl_format)
 {
   cl_int ret = CL_SUCCESS;
@@ -597,6 +597,21 @@ cl_buffer intel_share_buffer_from_libva(cl_context ctx,
   return (cl_buffer)intel_bo;
 }
 
+cl_buffer intel_share_image_from_libva(cl_context ctx,
+                                       unsigned int bo_name,
+                                       struct _cl_mem_image *image)
+{
+  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);
+
+  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 int32_t get_intel_tiling(cl_int tiling, uint32_t *intel_tiling)
 {
   switch (tiling) {
@@ -645,6 +660,7 @@ intel_setup_callbacks(void)
   intel_set_cl_gl_callbacks();
 #endif
   cl_buffer_get_buffer_from_libva = (cl_buffer_get_buffer_from_libva_cb *) intel_share_buffer_from_libva;
+  cl_buffer_get_image_from_libva = (cl_buffer_get_image_from_libva_cb *) intel_share_image_from_libva;
   cl_buffer_reference = (cl_buffer_reference_cb *) drm_intel_bo_reference;
   cl_buffer_unreference = (cl_buffer_unreference_cb *) drm_intel_bo_unreference;
   cl_buffer_map = (cl_buffer_map_cb *) drm_intel_bo_map;
diff --git a/src/intel/intel_gpgpu.c b/src/intel/intel_gpgpu.c
index 21cf09b..993f45e 100644
--- a/src/intel/intel_gpgpu.c
+++ b/src/intel/intel_gpgpu.c
@@ -477,7 +477,7 @@ intel_gpgpu_state_init(intel_gpgpu_t *gpgpu,
 }
 
 static void
-intel_gpgpu_set_buf_reloc_gen7(intel_gpgpu_t *gpgpu, int32_t index, dri_bo* obj_bo)
+intel_gpgpu_set_buf_reloc_gen7(intel_gpgpu_t *gpgpu, int32_t index, dri_bo* obj_bo, uint32_t obj_bo_offset)
 {
   surface_heap_t *heap = gpgpu->surface_heap_b.bo->virtual;
   heap->binding_table[index] = offsetof(surface_heap_t, surface) +
@@ -485,7 +485,7 @@ intel_gpgpu_set_buf_reloc_gen7(intel_gpgpu_t *gpgpu, int32_t index, dri_bo* obj_
   dri_bo_emit_reloc(gpgpu->surface_heap_b.bo,
                     I915_GEM_DOMAIN_RENDER,
                     I915_GEM_DOMAIN_RENDER,
-                    0,
+                    obj_bo_offset,
                     heap->binding_table[index] +
                     offsetof(gen7_surface_state_t, ss1),
                     obj_bo);
@@ -569,6 +569,7 @@ static void
 intel_gpgpu_bind_image_gen7(intel_gpgpu_t *gpgpu,
                               uint32_t index,
                               dri_bo* obj_bo,
+                              uint32_t obj_bo_offset,
                               uint32_t format,
                               cl_mem_object_type type,
                               int32_t w,
@@ -600,7 +601,7 @@ intel_gpgpu_bind_image_gen7(intel_gpgpu_t *gpgpu,
     ss->ss0.tile_walk = I965_TILEWALK_YMAJOR;
   }
   ss->ss0.render_cache_rw_mode = 1; /* XXX do we need to set it? */
-  intel_gpgpu_set_buf_reloc_gen7(gpgpu, index, obj_bo);
+  intel_gpgpu_set_buf_reloc_gen7(gpgpu, index, obj_bo, obj_bo_offset);
   gpgpu->binded_img[index - gpgpu->img_index_base] = obj_bo;
 }
 
@@ -642,6 +643,7 @@ static void
 intel_gpgpu_bind_image(intel_gpgpu_t *gpgpu,
                        uint32_t index,
                        cl_buffer *obj_bo,
+                       uint32_t obj_bo_offset,
                        uint32_t format,
                        cl_mem_object_type type,
                        int32_t w,
@@ -650,7 +652,7 @@ intel_gpgpu_bind_image(intel_gpgpu_t *gpgpu,
                        int32_t pitch,
                        cl_gpgpu_tiling tiling)
 {
-  intel_gpgpu_bind_image_gen7(gpgpu, index, (drm_intel_bo*) obj_bo, format, type, w, h, depth, pitch, tiling);
+  intel_gpgpu_bind_image_gen7(gpgpu, index, (drm_intel_bo*) obj_bo, obj_bo_offset, format, type, w, h, depth, pitch, tiling);
   assert(index < GEN_MAX_SURFACES);
 }
 



More information about the Beignet mailing list