[Beignet] [PATCH 1/2] CL: Refactor cl_mem's implementation.

Zhigang Gong zhigang.gong at gmail.com
Mon Aug 26 07:45:47 PDT 2013


The buffer object is much simpler than the image object.
We'd better to not use the same big data structure for
both objects.

Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
---
 src/cl_api.c           |   44 ++++++++---------
 src/cl_command_queue.c |   16 +++---
 src/cl_enqueue.c       |   19 +++++---
 src/cl_kernel.c        |    4 +-
 src/cl_mem.c           |  127 +++++++++++++++++++++++++-----------------------
 src/cl_mem.h           |   89 +++++++++++++++++++++++++++------
 src/cl_mem_gl.c        |   93 ++++++++++++++++-------------------
 src/cl_utils.h         |   10 ++--
 8 files changed, 234 insertions(+), 168 deletions(-)

diff --git a/src/cl_api.c b/src/cl_api.c
index 4f048ee..4e4cd6c 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -408,7 +408,7 @@ clCreateBuffer(cl_context    context,
   cl_int err = CL_SUCCESS;
   CHECK_CONTEXT (context);
 
-  mem = cl_mem_new(context, flags, size, host_ptr, &err);
+  mem = cl_mem_new_buffer(context, flags, size, host_ptr, &err);
 error:
   if (errcode_ret)
     *errcode_ret = err;
@@ -592,13 +592,13 @@ error:
 }
 
 cl_int
-clGetImageInfo(cl_mem         image,
+clGetImageInfo(cl_mem         mem,
                cl_image_info  param_name,
                size_t         param_value_size,
                void *         param_value,
                size_t *       param_value_size_ret)
 {
-  return cl_get_image_info(image,
+  return cl_get_image_info(mem,
                            param_name,
                            param_value_size,
                            param_value,
@@ -1356,7 +1356,7 @@ clEnqueueCopyBufferRect(cl_command_queue     command_queue,
 
 cl_int
 clEnqueueReadImage(cl_command_queue      command_queue,
-                   cl_mem                image,
+                   cl_mem                mem,
                    cl_bool               blocking_read,
                    const size_t *        origin,
                    const size_t *        region,
@@ -1371,8 +1371,8 @@ clEnqueueReadImage(cl_command_queue      command_queue,
   enqueue_data *data, no_wait_data = { 0 };
 
   CHECK_QUEUE(command_queue);
-  CHECK_IMAGE(image);
-  if (command_queue->ctx != image->ctx) {
+  CHECK_IMAGE(mem);
+  if (command_queue->ctx != mem->ctx) {
      err = CL_INVALID_CONTEXT;
      goto error;
   }
@@ -1410,16 +1410,16 @@ clEnqueueReadImage(cl_command_queue      command_queue,
      goto error;
   }
 
-  if (image->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) {
+  if (mem->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) {
      err = CL_INVALID_OPERATION;
      goto error;
   }
 
-  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list, event, image->ctx);
+  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list, event, mem->ctx);
 
   data = &no_wait_data;
   data->type        = EnqueueReadImage;
-  data->mem_obj     = image;
+  data->mem_obj     = mem;
   data->ptr         = ptr;
   data->origin[0]   = origin[0];  data->origin[1] = origin[1];  data->origin[2] = origin[2];
   data->region[0]   = region[0];  data->region[1] = region[1];  data->region[2] = region[2];
@@ -1438,7 +1438,7 @@ error:
 
 cl_int
 clEnqueueWriteImage(cl_command_queue     command_queue,
-                    cl_mem               image,
+                    cl_mem               mem,
                     cl_bool              blocking_write,
                     const size_t *       origin,
                     const size_t *       region,
@@ -1453,8 +1453,8 @@ clEnqueueWriteImage(cl_command_queue     command_queue,
   enqueue_data *data, no_wait_data = { 0 };
 
   CHECK_QUEUE(command_queue);
-  CHECK_IMAGE(image);
-  if (command_queue->ctx != image->ctx) {
+  CHECK_IMAGE(mem);
+  if (command_queue->ctx != mem->ctx) {
     err = CL_INVALID_CONTEXT;
     goto error;
   }
@@ -1492,16 +1492,16 @@ clEnqueueWriteImage(cl_command_queue     command_queue,
     goto error;
   }
 
-  if (image->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)) {
+  if (mem->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)) {
     err = CL_INVALID_OPERATION;
     goto error;
   }
 
-  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list, event, image->ctx);
+  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list, event, mem->ctx);
 
   data = &no_wait_data;
   data->type        = EnqueueWriteImage;
-  data->mem_obj     = image;
+  data->mem_obj     = mem;
   data->const_ptr   = ptr;
   data->origin[0]   = origin[0];  data->origin[1] = origin[1];  data->origin[2] = origin[2];
   data->region[0]   = region[0];  data->region[1] = region[1];  data->region[2] = region[2];
@@ -1625,7 +1625,7 @@ error:
 
 void *
 clEnqueueMapImage(cl_command_queue   command_queue,
-                  cl_mem             image,
+                  cl_mem             mem,
                   cl_bool            blocking_map,
                   cl_map_flags       map_flags,
                   const size_t *     origin,
@@ -1641,8 +1641,8 @@ clEnqueueMapImage(cl_command_queue   command_queue,
   enqueue_data *data, no_wait_data = { 0 };
 
   CHECK_QUEUE(command_queue);
-  CHECK_IMAGE(image);
-  if (command_queue->ctx != image->ctx) {
+  CHECK_IMAGE(mem);
+  if (command_queue->ctx != mem->ctx) {
     err = CL_INVALID_CONTEXT;
     goto error;
   }
@@ -1665,19 +1665,19 @@ clEnqueueMapImage(cl_command_queue   command_queue,
     *image_slice_pitch = image->slice_pitch;
 
   if ((map_flags & CL_MAP_READ &&
-       image->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) ||
+       mem->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) ||
       (map_flags & (CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION) &&
-       image->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)))
+       mem->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)))
   {
     err = CL_INVALID_OPERATION;
     goto error;
   }
 
-  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list, event, image->ctx);
+  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list, event, mem->ctx);
 
   data = &no_wait_data;
   data->type        = EnqueueMapImage;
-  data->mem_obj     = image;
+  data->mem_obj     = mem;
   data->origin[0]   = origin[0];  data->origin[1] = origin[1];  data->origin[2] = origin[2];
   data->region[0]   = region[0];  data->region[1] = region[1];  data->region[2] = region[2];
   data->row_pitch   = *image_row_pitch;
diff --git a/src/cl_command_queue.c b/src/cl_command_queue.c
index e82f75c..9606d6b 100644
--- a/src/cl_command_queue.c
+++ b/src/cl_command_queue.c
@@ -98,7 +98,9 @@ cl_command_queue_add_ref(cl_command_queue queue)
 }
 
 static void
-set_image_info(char *curbe, struct ImageInfo * image_info, cl_mem image)
+set_image_info(char *curbe,
+               struct ImageInfo * image_info,
+               struct _cl_mem_image *image)
 {
   if (image_info->wSlot >= 0)
     *(uint32_t*)(curbe + image_info->wSlot) = image->w;
@@ -118,12 +120,14 @@ cl_command_queue_bind_image(cl_command_queue queue, cl_kernel k)
   uint32_t i;
   for (i = 0; i < k->image_sz; i++) {
     int id = k->images[i].arg_idx;
+    struct _cl_mem_image *image;
     assert(gbe_kernel_get_arg_type(k->opaque, id) == GBE_ARG_IMAGE);
-    set_image_info(k->curbe, &k->images[i], k->args[id].mem);
-    cl_gpgpu_bind_image(queue->gpgpu, k->images[i].idx, k->args[id].mem->bo,
-                        k->args[id].mem->intel_fmt, k->args[id].mem->type,
-                        k->args[id].mem->w, k->args[id].mem->h,
-                        k->args[id].mem->row_pitch, k->args[id].mem->tiling);
+    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,
+                        image->intel_fmt, image->image_type,
+                        image->w, image->h,
+                        image->row_pitch, image->tiling);
   }
   return CL_SUCCESS;
 }
diff --git a/src/cl_enqueue.c b/src/cl_enqueue.c
index a112cc4..1e8de66 100644
--- a/src/cl_enqueue.c
+++ b/src/cl_enqueue.c
@@ -68,11 +68,12 @@ cl_int cl_enqueue_read_image(enqueue_data *data)
   cl_int err = CL_SUCCESS;
   void* src_ptr;
 
-  cl_mem image = data->mem_obj;
+  cl_mem mem = data->mem_obj;
+  CHECK_IMAGE(mem);
   const size_t* origin = data->origin;
   const size_t* region = data->region;
 
-  if (!(src_ptr = cl_mem_map_auto(image))) {
+  if (!(src_ptr = cl_mem_map_auto(mem))) {
     err = CL_MAP_FAILURE;
     goto error;
   }
@@ -100,7 +101,7 @@ cl_int cl_enqueue_read_image(enqueue_data *data)
     }
   }
 
- err = cl_mem_unmap_auto(image);
+ err = cl_mem_unmap_auto(mem);
 
 error:
   return err;
@@ -112,11 +113,12 @@ cl_int cl_enqueue_write_image(enqueue_data *data)
   cl_int err = CL_SUCCESS;
   void* dst_ptr;
 
-  cl_mem image = data->mem_obj;
+  cl_mem mem = data->mem_obj;
+  CHECK_IMAGE(mem);
   const size_t *origin = data->origin;
   const size_t *region = data->region;
 
-  if (!(dst_ptr = cl_mem_map_auto(image))) {
+  if (!(dst_ptr = cl_mem_map_auto(mem))) {
     err = CL_MAP_FAILURE;
     goto error;
   }
@@ -144,7 +146,7 @@ cl_int cl_enqueue_write_image(enqueue_data *data)
     }
   }
 
-  err = cl_mem_unmap_auto(image);
+  err = cl_mem_unmap_auto(mem);
 
 error:
   return err;
@@ -233,10 +235,11 @@ cl_int cl_enqueue_map_image(enqueue_data *data)
   void *ptr = NULL;
   cl_int err = CL_SUCCESS;
 
-  cl_mem image = data->mem_obj;
+  cl_mem mem = data->mem_obj;
+  CHECK_IMAGE(mem);
   const size_t *origin = data->origin;
 
-  if (!(ptr = cl_mem_map_auto(image))) {
+  if (!(ptr = cl_mem_map_auto(mem))) {
     err = CL_MAP_FAILURE;
     goto error;
   }
diff --git a/src/cl_kernel.c b/src/cl_kernel.c
index 41e6a8a..12a08c5 100644
--- a/src/cl_kernel.c
+++ b/src/cl_kernel.c
@@ -133,8 +133,8 @@ cl_kernel_set_arg(cl_kernel k, cl_uint index, size_t sz, const void *value)
       if (UNLIKELY(mem->magic != CL_MAGIC_MEM_HEADER))
         return CL_INVALID_MEM_OBJECT;
 
-      if (UNLIKELY((arg_type == GBE_ARG_IMAGE && !mem->is_image)
-         || (arg_type != GBE_ARG_IMAGE && mem->is_image)))
+      if (UNLIKELY((arg_type == GBE_ARG_IMAGE && !IS_IMAGE(mem))
+         || (arg_type != GBE_ARG_IMAGE && IS_IMAGE(mem))))
           return CL_INVALID_ARG_VALUE;
     }
   }
diff --git a/src/cl_mem.c b/src/cl_mem.c
index f794ce7..640ec08 100644
--- a/src/cl_mem.c
+++ b/src/cl_mem.c
@@ -106,8 +106,8 @@ cl_get_image_info(cl_mem mem,
                   void *param_value,
                   size_t *param_value_size_ret)
 {
-  if(!mem || !mem->is_image)
-    return CL_INVALID_MEM_OBJECT;
+  int err;
+  CHECK_IMAGE(mem);
 
   switch(param_name)
   {
@@ -125,35 +125,39 @@ cl_get_image_info(cl_mem mem,
   switch(param_name)
   {
   case CL_IMAGE_FORMAT:
-    *(cl_image_format *)param_value = mem->fmt;
+    *(cl_image_format *)param_value = image->fmt;
     break;
   case CL_IMAGE_ELEMENT_SIZE:
-    *(size_t *)param_value = mem->bpp;
+    *(size_t *)param_value = image->bpp;
     break;
   case CL_IMAGE_ROW_PITCH:
-    *(size_t *)param_value = mem->row_pitch;
+    *(size_t *)param_value = image->row_pitch;
     break;
   case CL_IMAGE_SLICE_PITCH:
-    *(size_t *)param_value = mem->slice_pitch;
+    *(size_t *)param_value = image->slice_pitch;
     break;
   case CL_IMAGE_WIDTH:
-    *(size_t *)param_value = mem->w;
+    *(size_t *)param_value = image->w;
     break;
   case CL_IMAGE_HEIGHT:
-    *(size_t *)param_value = mem->h;
+    *(size_t *)param_value = image->h;
     break;
   case CL_IMAGE_DEPTH:
-    *(size_t *)param_value = mem->depth;
+    *(size_t *)param_value = image->depth;
     break;
   }
 
   return CL_SUCCESS;
+
+error:
+    return err;
 }
 
 #undef FIELD_SIZE
 
-static cl_mem
-cl_mem_allocate(cl_context ctx,
+LOCAL cl_mem
+cl_mem_allocate(enum cl_mem_type type,
+                cl_context ctx,
                 cl_mem_flags flags,
                 size_t sz,
                 cl_int is_tiled,
@@ -161,6 +165,8 @@ cl_mem_allocate(cl_context ctx,
 {
   cl_buffer_mgr bufmgr = NULL;
   cl_mem mem = NULL;
+  struct _cl_mem_image *image = NULL;
+  struct _cl_mem_buffer *buffer = NULL;
   cl_int err = CL_SUCCESS;
   size_t alignment = 64;
   cl_ulong max_mem_size;
@@ -174,41 +180,51 @@ cl_mem_allocate(cl_context ctx,
                                 NULL)) != CL_SUCCESS) {
     goto error;
   }
-  if (UNLIKELY(sz == 0 || sz > max_mem_size)) {
+  if (UNLIKELY(sz > max_mem_size)) {
     err = CL_INVALID_BUFFER_SIZE;
     goto error;
   }
 
   /* Allocate and inialize the structure itself */
-  TRY_ALLOC (mem, CALLOC(struct _cl_mem));
+  if (type == CL_MEM_IMAGE_TYPE) {
+    TRY_ALLOC (image, CALLOC(struct _cl_mem_image));
+    mem = &image->base;
+  }
+  else {
+    TRY_ALLOC (buffer, CALLOC(struct _cl_mem_buffer));
+    mem = &buffer->base;
+  }
+  mem->type = type;
   SET_ICD(mem->dispatch)
   mem->ref_n = 1;
   mem->magic = CL_MAGIC_MEM_HEADER;
   mem->flags = flags;
 
-  /* Pinning will require stricter alignment rules */
-  if ((flags & CL_MEM_PINNABLE) || is_tiled)
-    alignment = 4096;
-
-  /* Allocate space in memory */
-  bufmgr = cl_context_get_bufmgr(ctx);
-  assert(bufmgr);
-  mem->bo = cl_buffer_alloc(bufmgr, "CL memory object", sz, alignment);
-  if (UNLIKELY(mem->bo == NULL)) {
-    err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
-    goto error;
+  if (sz != 0) {
+    /* Pinning will require stricter alignment rules */
+    if ((flags & CL_MEM_PINNABLE) || is_tiled)
+      alignment = 4096;
+
+    /* Allocate space in memory */
+    bufmgr = cl_context_get_bufmgr(ctx);
+    assert(bufmgr);
+    mem->bo = cl_buffer_alloc(bufmgr, "CL memory object", sz, alignment);
+    if (UNLIKELY(mem->bo == NULL)) {
+      err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
+      goto error;
+    }
+    mem->size = sz;
   }
-  mem->size = sz;
 
-  /* Append the buffer in the context buffer list */
+  cl_context_add_ref(ctx);
+  mem->ctx = ctx;
+    /* Append the buffer in the context buffer list */
   pthread_mutex_lock(&ctx->buffer_lock);
-    mem->next = ctx->buffers;
-    if (ctx->buffers != NULL)
-      ctx->buffers->prev = mem;
-    ctx->buffers = mem;
+  mem->next = ctx->buffers;
+  if (ctx->buffers != NULL)
+    ctx->buffers->prev = mem;
+  ctx->buffers = mem;
   pthread_mutex_unlock(&ctx->buffer_lock);
-  mem->ctx = ctx;
-  cl_context_add_ref(ctx);
 
 exit:
   if (errcode)
@@ -222,11 +238,11 @@ error:
 }
 
 LOCAL cl_mem
-cl_mem_new(cl_context ctx,
-           cl_mem_flags flags,
-           size_t sz,
-           void *data,
-           cl_int *errcode_ret)
+cl_mem_new_buffer(cl_context ctx,
+                  cl_mem_flags flags,
+                  size_t sz,
+                  void *data,
+                  cl_int *errcode_ret)
 {
   /* Possible mem type combination:
        CL_MEM_ALLOC_HOST_PTR
@@ -262,7 +278,7 @@ cl_mem_new(cl_context ctx,
   }
 
   /* Create the buffer in video memory */
-  mem = cl_mem_allocate(ctx, flags, sz, CL_FALSE, &err);
+  mem = cl_mem_allocate(CL_MEM_BUFFER_TYPE, ctx, flags, sz, CL_FALSE, &err);
   if (mem == NULL || err != CL_SUCCESS)
     goto error;
 
@@ -286,12 +302,12 @@ error:
 }
 
 static void
-cl_mem_copy_image(cl_mem image,
+cl_mem_copy_image(struct _cl_mem_image *image,
 		  size_t row_pitch,
 		  size_t slice_pitch,
 		  void* host_ptr)
 {
-  char* dst_ptr = cl_mem_map_auto(image);
+  char* dst_ptr = cl_mem_map_auto((cl_mem)image);
 
   if (row_pitch == image->row_pitch &&
       (image->depth == 1 || slice_pitch == image->slice_pitch))
@@ -313,7 +329,7 @@ cl_mem_copy_image(cl_mem image,
     }
   }
 
-  cl_mem_unmap_auto(image);
+  cl_mem_unmap_auto((cl_mem)image);
 }
 
 static const uint32_t tile_sz = 4096; /* 4KB per tile */
@@ -416,27 +432,19 @@ _cl_mem_new_image(cl_context ctx,
   }
 
   sz = aligned_pitch * aligned_h * depth;
-  mem = cl_mem_allocate(ctx, flags, sz, tiling != CL_NO_TILE, &err);
+  mem = cl_mem_allocate(CL_MEM_IMAGE_TYPE, ctx, flags, sz, tiling != CL_NO_TILE, &err);
   if (mem == NULL || err != CL_SUCCESS)
     goto error;
 
-  mem->w = w;
-  mem->h = h;
-  mem->depth = depth;
-  mem->fmt = *fmt;
-  mem->intel_fmt = intel_fmt;
-  mem->bpp = bpp;
-  mem->is_image = 1;
-  mem->row_pitch = aligned_pitch;
-  mem->slice_pitch = image_type == CL_MEM_OBJECT_IMAGE1D || image_type == CL_MEM_OBJECT_IMAGE2D ? 0 : aligned_pitch*aligned_h;
-  mem->tiling = tiling;
-  mem->type = image_type;
-
   cl_buffer_set_tiling(mem->bo, tiling, aligned_pitch);
+  slice_pitch = (image_type == CL_MEM_OBJECT_IMAGE1D
+                 || image_type == CL_MEM_OBJECT_IMAGE2D) ? 0 : aligned_pitch*aligned_h;
+
+  cl_mem_image_init(cl_mem_image(mem), w, h, image_type, depth, *fmt, intel_fmt, bpp, aligned_pitch, slice_pitch, tiling);
 
   /* Copy the data if required */
   if (flags & CL_MEM_COPY_HOST_PTR)
-    cl_mem_copy_image(mem, pitch, slice_pitch, data);
+    cl_mem_copy_image(cl_mem_image(mem), pitch, slice_pitch, data);
 
 exit:
   if (errcode_ret)
@@ -486,8 +494,8 @@ cl_mem_delete(cl_mem mem)
   if (LIKELY(mem->bo != NULL))
     cl_buffer_unreference(mem->bo);
 #ifdef HAS_EGL
-  if (UNLIKELY(mem->egl_image != NULL)) {
-     cl_mem_gl_delete(mem);
+  if (UNLIKELY(IS_IMAGE(mem) && cl_mem_image(mem)->egl_image != NULL)) {
+     cl_mem_gl_delete(cl_mem_image(mem));
   }
 #endif
 
@@ -562,7 +570,7 @@ cl_mem_unmap_gtt(cl_mem mem)
 LOCAL void*
 cl_mem_map_auto(cl_mem mem)
 {
-  if (mem->is_image && mem->tiling != CL_NO_TILE)
+  if (IS_IMAGE(mem) && cl_mem_image(mem)->tiling != CL_NO_TILE)
     return cl_mem_map_gtt(mem);
   else
     return cl_mem_map(mem);
@@ -571,7 +579,7 @@ cl_mem_map_auto(cl_mem mem)
 LOCAL cl_int
 cl_mem_unmap_auto(cl_mem mem)
 {
-  if (mem->is_image && mem->tiling != CL_NO_TILE)
+  if (IS_IMAGE(mem) && cl_mem_image(mem)->tiling != CL_NO_TILE)
     cl_buffer_unmap_gtt(mem->bo);
   else
     cl_buffer_unmap(mem->bo);
@@ -597,4 +605,3 @@ cl_mem_unpin(cl_mem mem)
   cl_buffer_unpin(mem->bo);
   return CL_SUCCESS;
 }
-
diff --git a/src/cl_mem.h b/src/cl_mem.h
index 1b1709a..a7a6ce4 100644
--- a/src/cl_mem.h
+++ b/src/cl_mem.h
@@ -23,6 +23,7 @@
 #include "cl_internals.h"
 #include "cl_driver.h"
 #include "CL/cl.h"
+#include <assert.h>
 
 #ifndef CL_VERSION_1_2
 #define CL_MEM_OBJECT_IMAGE1D                       0x10F4
@@ -62,31 +63,82 @@ typedef struct _cl_mem_dstr_cb {
 }cl_mem_dstr_cb;
 
 /* Used for buffers and images */
-struct _cl_mem {
-  DEFINE_ICD(dispatch)
+#define IS_IMAGE(mem) (mem->type == CL_MEM_IMAGE_TYPE)
+enum cl_mem_type {
+  CL_MEM_BUFFER_TYPE,
+  CL_MEM_IMAGE_TYPE
+};
+
+typedef  struct _cl_mem {
   uint64_t magic;           /* To identify it as a memory object */
+  DEFINE_ICD(dispatch)
+  cl_mem prev, next;        /* We chain the memory buffers together */
+  enum cl_mem_type type;
   volatile int ref_n;       /* This object is reference counted */
   cl_buffer bo;             /* Data in GPU memory */
-  void *egl_image;          /* created from external egl image*/
   size_t size;              /* original request size, not alignment size, used in constant buffer */
-  cl_mem prev, next;        /* We chain the memory buffers together */
   cl_context ctx;           /* Context it belongs to */
   cl_mem_flags flags;       /* Flags specified at the creation time */
-  uint32_t is_image;        /* Indicate if this is an image or not */
-  cl_image_format fmt;      /* only for images */
-  cl_mem_object_type type;  /* only for images 1D/2D...*/
-  size_t w,h,depth;         /* only for images (depth is only for 3D images) */
-  size_t row_pitch,slice_pitch;
-  uint32_t intel_fmt;       /* format to provide in the surface state */
-  uint32_t bpp;             /* number of bytes per pixel */
-  cl_image_tiling_t tiling; /* only IVB+ supports TILE_[X,Y] (image only) */
   void * host_ptr;          /* Pointer of the host mem specified by CL_MEM_ALLOC_HOST_PTR */
   cl_mapped_ptr* mapped_ptr;/* Store the mapped addresses and size by caller. */
   int mapped_ptr_sz;        /* The array size of mapped_ptr. */
   int map_ref;              /* The mapped count. */
   cl_mem_dstr_cb *dstr_cb;  /* The destroy callback. */
+} _cl_mem;
+
+struct _cl_mem_image {
+  _cl_mem base;
+  cl_image_format fmt;            /* only for images */
+  uint32_t intel_fmt;             /* format to provide in the surface state */
+  uint32_t bpp;                   /* number of bytes per pixel */
+  cl_mem_object_type image_type;  /* only for images 1D/2D...*/
+  size_t w, h, depth;             /* only for images (depth is only for 3D images) */
+  size_t row_pitch, 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;
+  void *egl_image;                /* created from external egl image*/
 };
 
+inline static void
+cl_mem_image_init(struct _cl_mem_image *image, size_t w, size_t h,
+                  cl_mem_object_type image_type,
+                  size_t depth, cl_image_format fmt,
+                  uint32_t intel_fmt, uint32_t bpp,
+                  size_t row_pitch, size_t slice_pitch,
+                  cl_image_tiling_t tiling)
+{
+  image->w = w;
+  image->h = h;
+  image->image_type = image_type;
+  image->depth = depth;
+  image->fmt = fmt;
+  image->intel_fmt = intel_fmt;
+  image->bpp = bpp;
+  image->row_pitch = row_pitch;
+  image->slice_pitch = slice_pitch;
+  image->tiling = tiling;
+}
+
+struct _cl_mem_buffer {
+  _cl_mem base;
+  size_t offset;
+};
+
+inline static struct _cl_mem_image *
+cl_mem_image(cl_mem mem)
+{
+  assert(IS_IMAGE(mem));
+  return (struct _cl_mem_image *)mem;
+}
+
+inline static struct _cl_mem_buffer *
+cl_mem_buffer(cl_mem mem)
+{
+  assert(!IS_IMAGE(mem));
+  return (struct _cl_mem_buffer *)mem;
+}
+
 /* Query information about a memory object */
 extern cl_int cl_get_mem_object_info(cl_mem, cl_mem_info, size_t, void *, size_t *);
 
@@ -94,7 +146,7 @@ extern cl_int cl_get_mem_object_info(cl_mem, cl_mem_info, size_t, void *, size_t
 extern cl_int cl_get_image_info(cl_mem, cl_image_info, size_t, void *, size_t *);
 
 /* Create a new memory object and initialize it with possible user data */
-extern cl_mem cl_mem_new(cl_context, cl_mem_flags, size_t, void*, cl_int*);
+extern cl_mem cl_mem_new_buffer(cl_context, cl_mem_flags, size_t, void*, cl_int*);
 
 /* Idem but this is an image */
 extern cl_mem
@@ -109,7 +161,7 @@ cl_mem_new_image(cl_context context,
 extern void cl_mem_delete(cl_mem);
 
 /* Destroy egl image. */
-extern void cl_mem_gl_delete(cl_mem);
+extern void cl_mem_gl_delete(struct _cl_mem_image *);
 
 /* Add one more reference to this object */
 extern void cl_mem_add_ref(cl_mem);
@@ -136,5 +188,14 @@ extern cl_int cl_mem_unmap_auto(cl_mem);
 extern cl_int cl_mem_pin(cl_mem);
 extern cl_int cl_mem_unpin(cl_mem);
 
+extern cl_mem
+cl_mem_allocate(enum cl_mem_type type,
+                cl_context ctx,
+                cl_mem_flags flags,
+                size_t sz,
+                cl_int is_tiled,
+                cl_int *errcode);
+
+
 #endif /* __CL_MEM_H__ */
 
diff --git a/src/cl_mem_gl.c b/src/cl_mem_gl.c
index f247171..c77bcb9 100644
--- a/src/cl_mem_gl.c
+++ b/src/cl_mem_gl.c
@@ -110,32 +110,34 @@ error:
 }
 
 static cl_mem_object_type
-get_mem_type_from_target(GLenum texture_target)
+get_mem_type_from_target(GLenum texture_target, cl_mem_object_type *type)
 {
   switch(texture_target) {
-  case GL_TEXTURE_1D: return CL_MEM_OBJECT_IMAGE1D;
-  case GL_TEXTURE_2D: return CL_MEM_OBJECT_IMAGE2D;
-  case GL_TEXTURE_3D: return CL_MEM_OBJECT_IMAGE3D;
-  case GL_TEXTURE_1D_ARRAY: return CL_MEM_OBJECT_IMAGE1D_ARRAY;
-  case GL_TEXTURE_2D_ARRAY: return CL_MEM_OBJECT_IMAGE2D_ARRAY;
+  case GL_TEXTURE_1D: *type = CL_MEM_OBJECT_IMAGE1D; break;
+  case GL_TEXTURE_2D: *type = CL_MEM_OBJECT_IMAGE2D; break;
+  case GL_TEXTURE_3D: *type = CL_MEM_OBJECT_IMAGE3D; break;
+  case GL_TEXTURE_1D_ARRAY: *type = CL_MEM_OBJECT_IMAGE1D_ARRAY; break;
+  case GL_TEXTURE_2D_ARRAY: *type = CL_MEM_OBJECT_IMAGE2D_ARRAY; break;
   default:
-    assert(0);
+    return -1;
   }
   return 0;
 }
 
-LOCAL cl_mem cl_mem_new_gl_buffer(cl_context ctx,
-                                  cl_mem_flags flags,
-                                  GLuint buf_obj, 
-                                  cl_int *errcode_ret)
+LOCAL cl_mem
+cl_mem_new_gl_buffer(cl_context ctx,
+                     cl_mem_flags flags,
+                     GLuint buf_obj,
+                     cl_int *errcode_ret)
 {
   NOT_IMPLEMENTED;
 }
 
-EGLImageKHR cl_create_textured_egl_image(cl_context ctx,
-                                         GLenum texture_target,
-                                         GLint miplevel,
-                                         GLuint texture)
+static EGLImageKHR
+cl_create_textured_egl_image(cl_context ctx,
+                             GLenum texture_target,
+                             GLint miplevel,
+                             GLuint texture)
 {
   struct cl_gl_ext_deps *egl_funcs;
   EGLDisplay egl_display;
@@ -153,12 +155,13 @@ EGLImageKHR cl_create_textured_egl_image(cl_context ctx,
                                            &egl_attribs[0]);
 }
 
-LOCAL cl_mem cl_mem_new_gl_texture(cl_context ctx,
-                                   cl_mem_flags flags,
-                                   GLenum texture_target,
-                                   GLint miplevel,
-                                   GLuint texture,
-                                   cl_int *errcode_ret)
+LOCAL cl_mem
+cl_mem_new_gl_texture(cl_context ctx,
+                      cl_mem_flags flags,
+                      GLenum texture_target,
+                      GLint miplevel,
+                      GLuint texture,
+                      cl_int *errcode_ret)
 {
   cl_int err = CL_SUCCESS;
   cl_mem mem = NULL;
@@ -173,17 +176,17 @@ LOCAL cl_mem cl_mem_new_gl_texture(cl_context ctx,
     goto error;
   }
 
-  TRY_ALLOC (mem, CALLOC(struct _cl_mem));
-  mem->ctx = ctx;
-  cl_context_add_ref(ctx);
+  mem = cl_mem_allocate(CL_MEM_IMAGE_TYPE, ctx, flags, 0, 0, errcode_ret);
+  if (mem == NULL) {
+    err = CL_OUT_OF_HOST_MEMORY;
+    goto error;
+  }
 
   egl_image = cl_create_textured_egl_image(ctx, texture_target, miplevel, texture);
-
   if (egl_image == NULL) {
     err = CL_INVALID_GL_OBJECT;
     goto error;
   }
-  mem->egl_image = egl_image;
   mem->bo = cl_buffer_alloc_from_eglimage(ctx, (void*)egl_image, &gl_format, &w, &h, &pitch, &tiling);
   if (UNLIKELY(mem->bo == NULL)) {
     err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
@@ -200,28 +203,14 @@ LOCAL cl_mem cl_mem_new_gl_texture(cl_context ctx,
   }
   cl_image_byte_per_pixel(&cl_format, &bpp);
 
-  mem->type = get_mem_type_from_target(texture_target);
-  mem->w = w;
-  mem->h = h;
-  mem->depth = 1;
-  mem->fmt = cl_format;
-  mem->intel_fmt = intel_fmt;
-  mem->bpp = bpp;
-  mem->is_image = 1;
-  mem->row_pitch = pitch;
-  mem->slice_pitch = 0;
-  mem->tiling = tiling;
-  mem->ref_n = 1;
-  mem->magic = CL_MAGIC_MEM_HEADER;
-  mem->flags = flags;
-
-  /* Append the buffer in the context buffer list */
-  pthread_mutex_lock(&ctx->buffer_lock);
-    mem->next = ctx->buffers;
-    if (ctx->buffers != NULL)
-      ctx->buffers->prev = mem;
-    ctx->buffers = mem;
-  pthread_mutex_unlock(&ctx->buffer_lock);
+  cl_mem_object_type image_type;
+  if (get_mem_type_from_target(texture_target, &image_type) != 0) {
+    err = CL_INVALID_IMAGE_DESCRIPTOR;
+    goto error;
+  }
+
+  cl_mem_image_init(cl_mem_image(mem), w, h, image_type, 1, cl_format, intel_fmt, bpp, pitch, 0, tiling);
+  cl_mem_image(mem)->egl_image = egl_image;
 
 exit:
   if (errcode_ret)
@@ -234,10 +223,10 @@ error:
 
 }
 
-LOCAL void cl_mem_gl_delete(cl_mem mem)
+LOCAL void cl_mem_gl_delete(struct _cl_mem_image *image)
 {
   struct cl_gl_ext_deps *egl_funcs;
-  EGLDisplay egl_display = (EGLDisplay)mem->ctx->props.egl_display;
-  egl_funcs =  CL_EXTENSION_GET_FUNCS(mem->ctx, khr_gl_sharing, gl_ext_deps);
-  egl_funcs->eglDestroyImageKHR_func(egl_display, mem->egl_image);
+  EGLDisplay egl_display = (EGLDisplay)image->base.ctx->props.egl_display;
+  egl_funcs =  CL_EXTENSION_GET_FUNCS(image->base.ctx, khr_gl_sharing, gl_ext_deps);
+  egl_funcs->eglDestroyImageKHR_func(egl_display, image->egl_image);
 }
diff --git a/src/cl_utils.h b/src/cl_utils.h
index bfe418d..5c523b2 100644
--- a/src/cl_utils.h
+++ b/src/cl_utils.h
@@ -138,14 +138,16 @@ do {                                                        \
   }                                                         \
 } while (0)
 
-#define CHECK_IMAGE(IMAGE)                                  \
-CHECK_MEM(image);                                           \
+#define CHECK_IMAGE(MEM)                                    \
+CHECK_MEM(MEM);                                             \
 do {                                                        \
-  if (UNLIKELY(!IMAGE->is_image)) {                         \
+  if (UNLIKELY(!IS_IMAGE(MEM))) {                           \
     err = CL_INVALID_MEM_OBJECT;                            \
     goto error;                                             \
   }                                                         \
-} while (0)
+} while (0);                                                \
+struct _cl_mem_image *image;                                \
+image = cl_mem_image(MEM);                                  \
 
 #define CHECK_EVENT(EVENT)                                    \
   do {                                                        \
-- 
1.7.9.5



More information about the Beignet mailing list