[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