diff options
author | Zhigang Gong <zhigang.gong@gmail.com> | 2013-08-26 22:45:47 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@linux.intel.com> | 2013-08-30 13:26:58 +0800 |
commit | 0a078725dd1b73f2d2174e52f47c7a3d565afe66 (patch) | |
tree | 043fd265a51132fc8a1d3dc06cbb5584ab554b61 /src | |
parent | a389dedab9bc94d3efcfbae1a06fe7b445d73332 (diff) |
CL: Refactor cl_mem's implementation.
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@linux.intel.com>
Reviewed-by: "Lu, Guanqun" <guanqun.lu@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/cl_api.c | 44 | ||||
-rw-r--r-- | src/cl_command_queue.c | 16 | ||||
-rw-r--r-- | src/cl_enqueue.c | 19 | ||||
-rw-r--r-- | src/cl_kernel.c | 4 | ||||
-rw-r--r-- | src/cl_mem.c | 127 | ||||
-rw-r--r-- | src/cl_mem.h | 89 | ||||
-rw-r--r-- | src/cl_mem_gl.c | 93 | ||||
-rw-r--r-- | 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 4f048ee7..4e4cd6c6 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 e82f75c9..9606d6be 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 a112cc47..1e8de663 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 41e6a8a4..12a08c55 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 f794ce73..640ec080 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 1b1709a8..a7a6ce45 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 f247171e..c77bcb90 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 bfe418d8..5c523b28 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 { \ |