From: Junyan He Date: Fri, 13 Jun 2014 07:07:52 +0000 (+0800) Subject: Add the support for 1D image from buffer. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d32fa1ac5e486db79ad4c9dd6f1861d13186ff3f;p=contrib%2Fbeignet.git Add the support for 1D image from buffer. Signed-off-by: Junyan He Reviewed-by: Zhigang Gong --- diff --git a/backend/src/ocl_stdlib.tmpl.h b/backend/src/ocl_stdlib.tmpl.h index 53253d0..a4bdfbd 100755 --- a/backend/src/ocl_stdlib.tmpl.h +++ b/backend/src/ocl_stdlib.tmpl.h @@ -92,6 +92,7 @@ typedef __texture struct _image3d_t* __image3d_t; typedef const ushort __sampler_t; typedef size_t __event_t; #define image1d_t __image1d_t +#define image1d_buffer_t __image1d_t #define image2d_t __image2d_t #define image3d_t __image3d_t #define sampler_t __sampler_t diff --git a/src/cl_device_id.c b/src/cl_device_id.c index 51d2e13..ee5120f 100644 --- a/src/cl_device_id.c +++ b/src/cl_device_id.c @@ -378,6 +378,7 @@ cl_get_device_info(cl_device_id device, DECL_FIELD(GLOBAL_MEM_CACHE_SIZE, global_mem_cache_size) DECL_FIELD(GLOBAL_MEM_SIZE, global_mem_size) DECL_FIELD(MAX_CONSTANT_BUFFER_SIZE, max_constant_buffer_size) + DECL_FIELD(IMAGE_MAX_BUFFER_SIZE, image_mem_size) DECL_FIELD(MAX_CONSTANT_ARGS, max_constant_args) DECL_FIELD(LOCAL_MEM_TYPE, local_mem_type) DECL_FIELD(LOCAL_MEM_SIZE, local_mem_size) diff --git a/src/cl_device_id.h b/src/cl_device_id.h index 5f7c9fe..2bbe98e 100644 --- a/src/cl_device_id.h +++ b/src/cl_device_id.h @@ -55,6 +55,7 @@ struct _cl_device_id { size_t image3d_max_width; size_t image3d_max_height; size_t image3d_max_depth; + cl_ulong image_mem_size; cl_uint max_samplers; size_t max_parameter_size; cl_uint mem_base_addr_align; diff --git a/src/cl_gt_device.h b/src/cl_gt_device.h index 3e2502c..cab2c58 100644 --- a/src/cl_gt_device.h +++ b/src/cl_gt_device.h @@ -46,6 +46,7 @@ .image3d_max_width = 8192, .image3d_max_height = 8192, .image3d_max_depth = 2048, +.image_mem_size = 8192, .max_samplers = 16, .mem_base_addr_align = sizeof(cl_long) * 16 * 8, .min_data_type_align_size = sizeof(cl_long) * 16, diff --git a/src/cl_mem.c b/src/cl_mem.c index 810c8a9..b4a5d81 100644 --- a/src/cl_mem.c +++ b/src/cl_mem.c @@ -153,10 +153,17 @@ cl_get_image_info(cl_mem mem, FIELD_SIZE(IMAGE_WIDTH, size_t); FIELD_SIZE(IMAGE_HEIGHT, size_t); FIELD_SIZE(IMAGE_DEPTH, size_t); + FIELD_SIZE(IMAGE_BUFFER, cl_mem); default: return CL_INVALID_VALUE; } + /* Do some further check. */ + if (param_name == CL_IMAGE_BUFFER && + image->image_type != CL_MEM_OBJECT_IMAGE1D_BUFFER) { + return CL_INVALID_VALUE; + } + switch(param_name) { case CL_IMAGE_FORMAT: @@ -180,6 +187,9 @@ cl_get_image_info(cl_mem mem, case CL_IMAGE_DEPTH: *(size_t *)param_value = image->depth; break; + case CL_IMAGE_BUFFER: + *(cl_mem *)param_value = image->buffer_1d; + break; } return CL_SUCCESS; @@ -677,6 +687,131 @@ error: goto exit; } +static cl_mem +_cl_mem_new_image_from_buffer(cl_context ctx, + cl_mem_flags flags, + const cl_image_format* image_format, + const cl_image_desc *image_desc, + cl_int *errcode_ret) +{ + cl_mem image = NULL; + cl_mem buffer = image_desc->buffer; + cl_int err = CL_SUCCESS; + *errcode_ret = err; + cl_ulong max_size; + cl_mem_flags merged_flags; + uint32_t bpp; + uint32_t intel_fmt = INTEL_UNSUPPORTED_FORMAT; + size_t offset = 0; + + /* Get the size of each pixel */ + if (UNLIKELY((err = cl_image_byte_per_pixel(image_format, &bpp)) != CL_SUCCESS)) + goto error; + + /* Only a sub-set of the formats are supported */ + intel_fmt = cl_image_get_intel_format(image_format); + if (UNLIKELY(intel_fmt == INTEL_UNSUPPORTED_FORMAT)) { + err = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; + goto error; + } + + if (!buffer) { + err = CL_INVALID_IMAGE_DESCRIPTOR; + goto error; + } + + if (flags & (CL_MEM_USE_HOST_PTR|CL_MEM_ALLOC_HOST_PTR|CL_MEM_COPY_HOST_PTR)) { + err = CL_INVALID_IMAGE_DESCRIPTOR; + goto error; + } + + /* access check. */ + if ((buffer->flags & CL_MEM_WRITE_ONLY) && + (flags & (CL_MEM_READ_WRITE|CL_MEM_READ_ONLY))) { + err = CL_INVALID_VALUE; + goto error; + } + if ((buffer->flags & CL_MEM_READ_ONLY) && + (flags & (CL_MEM_READ_WRITE|CL_MEM_WRITE_ONLY))) { + err = CL_INVALID_VALUE; + goto error; + } + if ((buffer->flags & CL_MEM_HOST_WRITE_ONLY) && + (flags & CL_MEM_HOST_READ_ONLY)) { + err = CL_INVALID_VALUE; + goto error; + } + if ((buffer->flags & CL_MEM_HOST_READ_ONLY) && + (flags & CL_MEM_HOST_WRITE_ONLY)) { + err = CL_INVALID_VALUE; + goto error; + } + if ((buffer->flags & CL_MEM_HOST_NO_ACCESS) && + (flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY))) { + err = CL_INVALID_VALUE; + goto error; + } + + if ((err = cl_get_device_info(ctx->device, + CL_DEVICE_IMAGE_MAX_BUFFER_SIZE, + sizeof(max_size), + &max_size, + NULL)) != CL_SUCCESS) { + goto error; + } + + if (image_desc->image_width > max_size) { + err = CL_INVALID_IMAGE_DESCRIPTOR; + goto error; + } + + if (image_desc->image_width*bpp > buffer->size) { + err = CL_INVALID_IMAGE_DESCRIPTOR; + goto error; + } + + merged_flags = buffer->flags; + if (flags & (CL_MEM_READ_WRITE|CL_MEM_READ_WRITE|CL_MEM_WRITE_ONLY)) { + merged_flags &= ~(CL_MEM_READ_WRITE|CL_MEM_READ_WRITE|CL_MEM_WRITE_ONLY); + merged_flags |= flags & (CL_MEM_READ_WRITE|CL_MEM_READ_WRITE|CL_MEM_WRITE_ONLY); + } + if (flags & (CL_MEM_HOST_WRITE_ONLY|CL_MEM_HOST_READ_ONLY|CL_MEM_HOST_NO_ACCESS)) { + merged_flags &= ~(CL_MEM_HOST_WRITE_ONLY|CL_MEM_HOST_READ_ONLY|CL_MEM_HOST_NO_ACCESS); + merged_flags |= flags & (CL_MEM_HOST_WRITE_ONLY|CL_MEM_HOST_READ_ONLY|CL_MEM_HOST_NO_ACCESS); + } + + /* Because the buffer is NO_TILING, the image should be no tiling. */ + image = cl_mem_allocate(CL_MEM_IMAGE_TYPE, ctx, flags, merged_flags, CL_FALSE, &err); + if (image == NULL || err != CL_SUCCESS) + goto error; + + cl_buffer_reference(buffer->bo); + image->bo = buffer->bo; + image->size = buffer->size; + /* If it is a sub buffer, we need to start from the sub offset. */ + if (buffer->type == CL_MEM_SUBBUFFER_TYPE) { + offset = ((struct _cl_mem_buffer *)buffer)->sub_offset; + } + if (image->flags & CL_MEM_USE_HOST_PTR) { + /* Now point to the right offset if buffer is a SUB_BUFFER. */ + image->host_ptr = buffer->host_ptr + offset; + } + + cl_mem_image_init(cl_mem_image(image), image_desc->image_width, 1, image_desc->image_type, + 1, *image_format, intel_fmt, bpp, image_desc->image_width*bpp, 0, CL_NO_TILE, + 0, 0, offset); + cl_mem_add_ref(buffer); + cl_mem_image(image)->buffer_1d = buffer; + return image; + +error: + if (image) + cl_mem_delete(image); + image = NULL; + *errcode_ret = err; + return image; +} + LOCAL cl_mem cl_mem_new_image(cl_context context, cl_mem_flags flags, @@ -695,8 +830,10 @@ cl_mem_new_image(cl_context context, host_ptr, errcode_ret); case CL_MEM_OBJECT_IMAGE2D_ARRAY: case CL_MEM_OBJECT_IMAGE1D_ARRAY: - case CL_MEM_OBJECT_IMAGE1D_BUFFER: NOT_IMPLEMENTED; + case CL_MEM_OBJECT_IMAGE1D_BUFFER: + return _cl_mem_new_image_from_buffer(context, flags, image_format, + image_desc, errcode_ret); break; case CL_MEM_OBJECT_BUFFER: default: @@ -719,6 +856,15 @@ cl_mem_delete(cl_mem mem) } #endif + /* iff we are a image, delete the 1d buffer if has. */ + if (IS_IMAGE(mem)) { + if (cl_mem_image(mem)->buffer_1d) { + assert(cl_mem_image(mem)->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER); + cl_mem_delete(cl_mem_image(mem)->buffer_1d); + cl_mem_image(mem)->buffer_1d = NULL; + } + } + /* Remove it from the list */ assert(mem->ctx); pthread_mutex_lock(&mem->ctx->buffer_lock); diff --git a/src/cl_mem.h b/src/cl_mem.h index c0f902e..d589093 100644 --- a/src/cl_mem.h +++ b/src/cl_mem.h @@ -103,6 +103,7 @@ struct _cl_mem_image { 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; /* offset for dri_bo, used when it's reloc. */ + cl_mem buffer_1d; /* if the image is created from buffer, it point to the buffer.*/ }; struct _cl_mem_gl_image { diff --git a/src/intel/intel_gpgpu.c b/src/intel/intel_gpgpu.c index cae843b..1da6400 100644 --- a/src/intel/intel_gpgpu.c +++ b/src/intel/intel_gpgpu.c @@ -715,10 +715,11 @@ static int intel_get_surface_type(cl_mem_object_type type) { switch (type) { + case CL_MEM_OBJECT_IMAGE1D_BUFFER: case CL_MEM_OBJECT_IMAGE1D: return I965_SURFACE_1D; + case CL_MEM_OBJECT_IMAGE2D: return I965_SURFACE_2D; case CL_MEM_OBJECT_IMAGE3D: return I965_SURFACE_3D; - case CL_MEM_OBJECT_IMAGE1D_BUFFER: case CL_MEM_OBJECT_IMAGE2D_ARRAY: case CL_MEM_OBJECT_IMAGE1D_ARRAY: NOT_IMPLEMENTED;