Home | History | Annotate | Download | only in ocl
      1 /*
      2  * cl_memory.cpp - CL memory
      3  *
      4  *  Copyright (c) 2015 Intel Corporation
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *      http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  *
     18  * Author: Wind Yuan <feng.yuan (at) intel.com>
     19  */
     20 
     21 #include "cl_utils.h"
     22 #include "cl_memory.h"
     23 #if HAVE_LIBDRM
     24 #include "intel/cl_va_memory.h"
     25 #endif
     26 
     27 namespace XCam {
     28 
     29 CLImageDesc::CLImageDesc ()
     30     : format {CL_R, CL_UNORM_INT8}
     31     , width (0)
     32     , height (0)
     33     , row_pitch (0)
     34     , slice_pitch (0)
     35     , array_size (0)
     36     , size (0)
     37 {
     38 }
     39 
     40 bool
     41 CLImageDesc::operator == (const CLImageDesc& desc) const
     42 {
     43     if (desc.format.image_channel_data_type == this->format.image_channel_data_type &&
     44             desc.format.image_channel_order == this->format.image_channel_order &&
     45             desc.width == this->width &&
     46             desc.height == this->height &&
     47             desc.row_pitch == this->row_pitch &&
     48             desc.slice_pitch == this->slice_pitch &&
     49             desc.array_size == this->array_size)// &&
     50         //desc.size == this->size)
     51         return true;
     52     return false;
     53 }
     54 
     55 CLMemory::CLMemory (const SmartPtr<CLContext> &context)
     56     : _context (context)
     57     , _mem_id (NULL)
     58     , _mem_fd (-1)
     59     , _mem_need_destroy (true)
     60     , _mapped_ptr (NULL)
     61 {
     62     XCAM_ASSERT (context.ptr () && context->is_valid ());
     63 }
     64 
     65 CLMemory::~CLMemory ()
     66 {
     67     release_fd ();
     68 
     69     if (_mapped_ptr)
     70         enqueue_unmap (_mapped_ptr);
     71 
     72     if (_mem_id && _mem_need_destroy) {
     73         _context->destroy_mem (_mem_id);
     74     }
     75 }
     76 
     77 int32_t
     78 CLMemory::export_fd ()
     79 {
     80     if (_mem_fd >= 0)
     81         return _mem_fd;
     82 
     83 #if HAVE_LIBDRM
     84     SmartPtr<CLIntelContext> context = _context.dynamic_cast_ptr<CLIntelContext> ();
     85     _mem_fd = context->export_mem_fd (_mem_id);
     86 #endif
     87     if (_mem_fd < 0)
     88         XCAM_LOG_ERROR ("invalid fd:%d", _mem_fd);
     89 
     90     return _mem_fd;
     91 }
     92 
     93 void
     94 CLMemory::release_fd ()
     95 {
     96     if (_mem_fd <= 0)
     97         return;
     98 
     99     close (_mem_fd);
    100     _mem_fd = -1;
    101 }
    102 
    103 XCamReturn
    104 CLMemory::enqueue_unmap (
    105     void *ptr,
    106     CLEventList &event_waits,
    107     SmartPtr<CLEvent> &event_out)
    108 {
    109     SmartPtr<CLContext> context = get_context ();
    110     cl_mem mem_id = get_mem_id ();
    111 
    112     XCAM_ASSERT (is_valid ());
    113     if (!is_valid ())
    114         return XCAM_RETURN_ERROR_PARAM;
    115 
    116     XCAM_ASSERT (ptr == _mapped_ptr);
    117     if (ptr == _mapped_ptr)
    118         _mapped_ptr = NULL;
    119 
    120     return context->enqueue_unmap (mem_id, ptr, event_waits, event_out);
    121 }
    122 
    123 bool CLMemory::get_cl_mem_info (
    124     cl_image_info param_name, size_t param_size,
    125     void *param, size_t *param_size_ret)
    126 {
    127     cl_mem mem_id = get_mem_id ();
    128     cl_int error_code = CL_SUCCESS;
    129     if (!mem_id)
    130         return false;
    131 
    132     error_code = clGetMemObjectInfo (mem_id, param_name, param_size, param, param_size_ret);
    133     XCAM_FAIL_RETURN(
    134         WARNING,
    135         error_code == CL_SUCCESS,
    136         false,
    137         "clGetMemObjectInfo failed on param:%d, errno:%d", param_name, error_code);
    138     return true;
    139 }
    140 
    141 CLBuffer::CLBuffer (const SmartPtr<CLContext> &context)
    142     : CLMemory (context)
    143 {
    144 }
    145 
    146 CLBuffer::CLBuffer (
    147     const SmartPtr<CLContext> &context, uint32_t size,
    148     cl_mem_flags  flags, void *host_ptr)
    149     : CLMemory (context)
    150     , _flags (flags)
    151     , _size (size)
    152 {
    153     init_buffer (context, size, flags, host_ptr);
    154 }
    155 
    156 bool
    157 CLBuffer::init_buffer (
    158     const SmartPtr<CLContext> &context, uint32_t size,
    159     cl_mem_flags  flags, void *host_ptr)
    160 {
    161     cl_mem mem_id = NULL;
    162 
    163     mem_id = context->create_buffer (size, flags, host_ptr);
    164     if (mem_id == NULL) {
    165         XCAM_LOG_WARNING ("CLBuffer create buffer failed");
    166         return false;
    167     }
    168 
    169     set_mem_id (mem_id);
    170     return true;
    171 }
    172 
    173 CLSubBuffer::CLSubBuffer (
    174     const SmartPtr<CLContext> &context, SmartPtr<CLBuffer> main_buf,
    175     cl_mem_flags flags, uint32_t offset, uint32_t size)
    176     : CLBuffer (context)
    177     , _main_buf (main_buf)
    178     , _flags (flags)
    179     , _size (size)
    180 {
    181     init_sub_buffer (context, main_buf, flags, offset, size);
    182 }
    183 
    184 bool
    185 CLSubBuffer::init_sub_buffer (
    186     const SmartPtr<CLContext> &context,
    187     SmartPtr<CLBuffer> main_buf,
    188     cl_mem_flags flags,
    189     uint32_t offset,
    190     uint32_t size)
    191 {
    192     cl_mem sub_mem = NULL;
    193     cl_mem main_mem = main_buf->get_mem_id ();
    194     XCAM_FAIL_RETURN (ERROR, main_mem != NULL, false, "get memory from main image failed");
    195 
    196     cl_buffer_region region;
    197     region.origin = offset;
    198     region.size = size;
    199 
    200     sub_mem = context->create_sub_buffer (main_mem, region, flags);
    201     if (sub_mem == NULL) {
    202         XCAM_LOG_WARNING ("CLBuffer create sub buffer failed");
    203         return false;
    204     }
    205 
    206     set_mem_id (sub_mem);
    207     return true;
    208 }
    209 
    210 XCamReturn
    211 CLBuffer::enqueue_read (
    212     void *ptr, uint32_t offset, uint32_t size,
    213     CLEventList &event_waits,
    214     SmartPtr<CLEvent> &event_out)
    215 {
    216     SmartPtr<CLContext> context = get_context ();
    217     cl_mem mem_id = get_mem_id ();
    218 
    219     XCAM_ASSERT (is_valid ());
    220     if (!is_valid ())
    221         return XCAM_RETURN_ERROR_PARAM;
    222 
    223     return context->enqueue_read_buffer (mem_id, ptr, offset, size, true, event_waits, event_out);
    224 }
    225 
    226 XCamReturn
    227 CLBuffer::enqueue_write (
    228     void *ptr, uint32_t offset, uint32_t size,
    229     CLEventList &event_waits,
    230     SmartPtr<CLEvent> &event_out)
    231 {
    232     SmartPtr<CLContext> context = get_context ();
    233     cl_mem mem_id = get_mem_id ();
    234 
    235     XCAM_ASSERT (is_valid ());
    236     if (!is_valid ())
    237         return XCAM_RETURN_ERROR_PARAM;
    238 
    239     return context->enqueue_write_buffer (mem_id, ptr, offset, size, true, event_waits, event_out);
    240 }
    241 
    242 XCamReturn
    243 CLBuffer::enqueue_map (
    244     void *&ptr, uint32_t offset, uint32_t size,
    245     cl_map_flags map_flags,
    246     CLEventList &event_waits,
    247     SmartPtr<CLEvent> &event_out)
    248 {
    249     SmartPtr<CLContext> context = get_context ();
    250     cl_mem mem_id = get_mem_id ();
    251     XCamReturn ret = XCAM_RETURN_NO_ERROR;
    252 
    253     XCAM_ASSERT (is_valid ());
    254     if (!is_valid ())
    255         return XCAM_RETURN_ERROR_PARAM;
    256 
    257     ret = context->enqueue_map_buffer (mem_id, ptr, offset, size, true, map_flags, event_waits, event_out);
    258     XCAM_FAIL_RETURN (
    259         WARNING,
    260         ret == XCAM_RETURN_NO_ERROR,
    261         ret,
    262         "enqueue_map failed ");
    263 
    264     set_mapped_ptr (ptr);
    265     return ret;
    266 }
    267 
    268 CLImage::CLImage (const SmartPtr<CLContext> &context)
    269     : CLMemory (context)
    270 {
    271 }
    272 
    273 uint32_t
    274 CLImage::get_pixel_bytes () const
    275 {
    276     return calculate_pixel_bytes(_image_desc.format);
    277 }
    278 
    279 bool
    280 CLImage::get_cl_image_info (cl_image_info param_name, size_t param_size, void *param, size_t *param_size_ret)
    281 {
    282     cl_mem mem_id = get_mem_id ();
    283     cl_int error_code = CL_SUCCESS;
    284     if (!mem_id)
    285         return false;
    286 
    287     error_code = clGetImageInfo (mem_id, param_name, param_size, param, param_size_ret);
    288     XCAM_FAIL_RETURN(
    289         WARNING,
    290         error_code == CL_SUCCESS,
    291         false,
    292         "clGetImageInfo failed on param:%d, errno:%d", param_name, error_code);
    293     return true;
    294 }
    295 
    296 uint32_t
    297 CLImage::calculate_pixel_bytes (const cl_image_format &fmt)
    298 {
    299     uint32_t a = 0, b = 0;
    300     switch (fmt.image_channel_order) {
    301     case CL_R:
    302     case CL_A:
    303     case CL_Rx:
    304         a = 1;
    305         break;
    306     case CL_RG:
    307     case CL_RA:
    308     case CL_RGx:
    309         a = 2;
    310         break;
    311     case CL_RGB:
    312     case CL_RGBx:
    313         a = 3;
    314         break;
    315     case CL_RGBA:
    316     case CL_BGRA:
    317     case CL_ARGB:
    318         a = 4;
    319         break;
    320     default:
    321         XCAM_LOG_DEBUG ("calculate_pixel_bytes with wrong channel_order:0x%04x", fmt.image_channel_order);
    322         return 0;
    323     }
    324 
    325     switch (fmt.image_channel_data_type) {
    326     case CL_UNORM_INT8:
    327     case CL_SNORM_INT8:
    328     case CL_SIGNED_INT8:
    329     case CL_UNSIGNED_INT8:
    330         b = 1;
    331         break;
    332     case CL_SNORM_INT16:
    333     case CL_UNORM_INT16:
    334     case CL_SIGNED_INT16:
    335     case CL_UNSIGNED_INT16:
    336     case CL_HALF_FLOAT:
    337         b = 2;
    338         break;
    339     case CL_UNORM_INT24:
    340         b = 3;
    341         break;
    342     case CL_SIGNED_INT32:
    343     case CL_UNSIGNED_INT32:
    344     case CL_FLOAT:
    345         b = 4;
    346         break;
    347     default:
    348         XCAM_LOG_DEBUG ("calculate_pixel_bytes with wrong channel_data_type:0x%04x", fmt.image_channel_data_type);
    349         return 0;
    350     }
    351 
    352     return a * b;
    353 }
    354 
    355 bool
    356 CLImage::video_info_2_cl_image_desc (
    357     const VideoBufferInfo & video_info,
    358     CLImageDesc &image_desc)
    359 {
    360     image_desc.width = video_info.width;
    361     image_desc.height = video_info.height;
    362     image_desc.array_size = 0;
    363     image_desc.row_pitch = video_info.strides[0];
    364     XCAM_ASSERT (image_desc.row_pitch >= image_desc.width);
    365     image_desc.slice_pitch = 0;
    366 
    367     switch (video_info.format) {
    368     case XCAM_PIX_FMT_RGB48:
    369         //cl_image_info.fmt.image_channel_order = CL_RGB;
    370         //cl_image_info.fmt.image_channel_data_type = CL_UNORM_INT16;
    371         XCAM_LOG_WARNING (
    372             "video_info to cl_image_info doesn't support XCAM_PIX_FMT_RGB48, maybe try XCAM_PIX_FMT_RGBA64 instread\n"
    373             " **** XCAM_PIX_FMT_RGB48 need check with cl implementation ****");
    374         return false;
    375         break;
    376     case V4L2_PIX_FMT_GREY:
    377         image_desc.format.image_channel_order = CL_R;
    378         image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    379         break;
    380 
    381     case XCAM_PIX_FMT_RGBA64:
    382         image_desc.format.image_channel_order = CL_RGBA;
    383         image_desc.format.image_channel_data_type = CL_UNORM_INT16;
    384         break;
    385 
    386     case V4L2_PIX_FMT_RGB24:
    387         image_desc.format.image_channel_order = CL_RGB;
    388         image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    389         break;
    390 
    391     case V4L2_PIX_FMT_RGB565:
    392         image_desc.format.image_channel_order = CL_RGB;
    393         image_desc.format.image_channel_data_type = CL_UNORM_SHORT_565;
    394         break;
    395     case V4L2_PIX_FMT_XBGR32:
    396     case V4L2_PIX_FMT_ABGR32:
    397     case V4L2_PIX_FMT_BGR32:
    398         image_desc.format.image_channel_order = CL_BGRA;
    399         image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    400         break;
    401         // cl doesn'tn support ARGB32 up to now, how about consider V4L2_PIX_FMT_RGBA32
    402     case V4L2_PIX_FMT_RGB32:
    403     case V4L2_PIX_FMT_ARGB32:
    404     case V4L2_PIX_FMT_XRGB32:
    405         image_desc.format.image_channel_order = CL_ARGB;
    406         image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    407         break;
    408 
    409     case V4L2_PIX_FMT_RGBA32:
    410         image_desc.format.image_channel_order = CL_RGBA;
    411         image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    412         break;
    413 
    414     case V4L2_PIX_FMT_SBGGR10:
    415     case V4L2_PIX_FMT_SGBRG10:
    416     case V4L2_PIX_FMT_SGRBG10:
    417     case V4L2_PIX_FMT_SRGGB10:
    418     case V4L2_PIX_FMT_SBGGR12:
    419     case V4L2_PIX_FMT_SGBRG12:
    420     case V4L2_PIX_FMT_SGRBG12:
    421     case V4L2_PIX_FMT_SRGGB12:
    422     case V4L2_PIX_FMT_SBGGR16:
    423     case XCAM_PIX_FMT_SGRBG16:
    424         image_desc.format.image_channel_order = CL_R;
    425         image_desc.format.image_channel_data_type = CL_UNORM_INT16;
    426         break;
    427 
    428     case V4L2_PIX_FMT_SBGGR8:
    429     case V4L2_PIX_FMT_SGBRG8:
    430     case V4L2_PIX_FMT_SGRBG8:
    431     case V4L2_PIX_FMT_SRGGB8:
    432         image_desc.format.image_channel_order = CL_R;
    433         image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    434         break;
    435 
    436     case V4L2_PIX_FMT_NV12:
    437         image_desc.format.image_channel_order = CL_R;
    438         image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    439         image_desc.array_size = 2;
    440         image_desc.slice_pitch = video_info.strides [0] * video_info.aligned_height;
    441         break;
    442 
    443     case V4L2_PIX_FMT_YUYV:
    444         image_desc.format.image_channel_order = CL_RGBA;
    445         image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    446         image_desc.width /= 2;
    447         break;
    448 
    449     case XCAM_PIX_FMT_LAB:
    450         image_desc.format.image_channel_order = CL_R;
    451         image_desc.format.image_channel_data_type = CL_FLOAT;
    452         break;
    453 
    454     case XCAM_PIX_FMT_RGB48_planar:
    455     case XCAM_PIX_FMT_RGB24_planar:
    456         image_desc.format.image_channel_order = CL_RGBA;
    457         if (XCAM_PIX_FMT_RGB48_planar == video_info.format)
    458             image_desc.format.image_channel_data_type = CL_UNORM_INT16;
    459         else
    460             image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    461         image_desc.width = video_info.aligned_width / 4;
    462         image_desc.array_size = 3;
    463         image_desc.slice_pitch = video_info.strides [0] * video_info.aligned_height;
    464         break;
    465 
    466     case XCAM_PIX_FMT_SGRBG16_planar:
    467     case XCAM_PIX_FMT_SGRBG8_planar:
    468         image_desc.format.image_channel_order = CL_RGBA;
    469         if (XCAM_PIX_FMT_SGRBG16_planar == video_info.format)
    470             image_desc.format.image_channel_data_type = CL_UNORM_INT16;
    471         else
    472             image_desc.format.image_channel_data_type = CL_UNORM_INT8;
    473         image_desc.width = video_info.aligned_width / 4;
    474         image_desc.array_size = 4;
    475         image_desc.slice_pitch = video_info.strides [0] * video_info.aligned_height;
    476         break;
    477 
    478     default:
    479         XCAM_LOG_WARNING (
    480             "video_info to cl_image_info doesn't support format:%s",
    481             xcam_fourcc_to_string (video_info.format));
    482         return false;
    483     }
    484 
    485     return true;
    486 }
    487 
    488 void
    489 CLImage::init_desc_by_image ()
    490 {
    491     size_t width = 0, height = 0, row_pitch = 0, slice_pitch = 0, array_size = 0, mem_size = 0;
    492     cl_image_format format = {CL_R, CL_UNORM_INT8};
    493 
    494     get_cl_image_info (CL_IMAGE_FORMAT, sizeof(format), &format);
    495     get_cl_image_info (CL_IMAGE_WIDTH, sizeof(width), &width);
    496     get_cl_image_info (CL_IMAGE_HEIGHT, sizeof(height), &height);
    497     get_cl_image_info (CL_IMAGE_ROW_PITCH, sizeof(row_pitch), &row_pitch);
    498     get_cl_image_info (CL_IMAGE_SLICE_PITCH, sizeof(slice_pitch), &slice_pitch);
    499     get_cl_image_info (CL_IMAGE_ARRAY_SIZE, sizeof(array_size), &array_size);
    500     get_cl_mem_info (CL_MEM_SIZE, sizeof(mem_size), &mem_size);
    501 
    502     _image_desc.format = format;
    503     _image_desc.width = width;
    504     _image_desc.height = height;
    505     _image_desc.row_pitch = row_pitch;
    506     _image_desc.slice_pitch = slice_pitch;
    507     _image_desc.array_size = array_size;
    508     _image_desc.size = mem_size;
    509 }
    510 
    511 XCamReturn
    512 CLImage::enqueue_map (
    513     void *&ptr,
    514     size_t *origin, size_t *region,
    515     size_t *row_pitch, size_t *slice_pitch,
    516     cl_map_flags map_flags,
    517     CLEventList &event_waits,
    518     SmartPtr<CLEvent> &event_out)
    519 {
    520     SmartPtr<CLContext> context = get_context ();
    521     cl_mem mem_id = get_mem_id ();
    522     XCamReturn ret = XCAM_RETURN_NO_ERROR;
    523 
    524     XCAM_ASSERT (is_valid ());
    525     if (!is_valid ())
    526         return XCAM_RETURN_ERROR_PARAM;
    527 
    528     ret = context->enqueue_map_image (mem_id, ptr, origin, region, row_pitch, slice_pitch, true, map_flags, event_waits, event_out);
    529     XCAM_FAIL_RETURN (
    530         WARNING,
    531         ret == XCAM_RETURN_NO_ERROR,
    532         ret,
    533         "enqueue_map failed ");
    534 
    535     set_mapped_ptr (ptr);
    536     return ret;
    537 }
    538 
    539 CLImage2D::CLImage2D (
    540     const SmartPtr<CLContext> &context,
    541     const VideoBufferInfo &video_info,
    542     cl_mem_flags  flags)
    543     : CLImage (context)
    544 {
    545     CLImageDesc cl_desc;
    546 
    547     if (!video_info_2_cl_image_desc (video_info, cl_desc)) {
    548         XCAM_LOG_WARNING ("CLVaImage create va image failed on default videoinfo");
    549         return;
    550     }
    551 
    552     init_image_2d (context, cl_desc, flags);
    553 }
    554 
    555 CLImage2D::CLImage2D (
    556     const SmartPtr<CLContext> &context,
    557     const CLImageDesc &cl_desc,
    558     cl_mem_flags  flags,
    559     SmartPtr<CLBuffer> bind_buf)
    560     : CLImage (context)
    561 {
    562     _bind_buf = bind_buf;
    563     init_image_2d (context, cl_desc, flags);
    564 }
    565 
    566 bool CLImage2D::init_image_2d (
    567     const SmartPtr<CLContext> &context,
    568     const CLImageDesc &desc,
    569     cl_mem_flags  flags)
    570 {
    571     cl_mem mem_id = 0;
    572     cl_image_desc cl_desc;
    573 
    574     xcam_mem_clear (cl_desc);
    575     cl_desc.image_type = CL_MEM_OBJECT_IMAGE2D;
    576     cl_desc.image_width = desc.width;
    577     cl_desc.image_height = desc.height;
    578     cl_desc.image_depth = 1;
    579     cl_desc.image_array_size = 0;
    580     cl_desc.image_row_pitch = 0;
    581     cl_desc.image_slice_pitch = 0;
    582     cl_desc.num_mip_levels = 0;
    583     cl_desc.num_samples = 0;
    584     cl_desc.buffer = NULL;
    585     if (_bind_buf.ptr ()) {
    586         if (desc.row_pitch)
    587             cl_desc.image_row_pitch = desc.row_pitch;
    588         else {
    589             cl_desc.image_row_pitch = calculate_pixel_bytes(desc.format) * desc.width;
    590         }
    591         XCAM_ASSERT (cl_desc.image_row_pitch);
    592         cl_desc.buffer = _bind_buf->get_mem_id ();
    593         XCAM_ASSERT (cl_desc.buffer);
    594     }
    595 
    596     mem_id = context->create_image (flags, desc.format, cl_desc);
    597     if (mem_id == NULL) {
    598         XCAM_LOG_WARNING ("CLImage2D create image 2d failed");
    599         return false;
    600     }
    601     set_mem_id (mem_id);
    602     init_desc_by_image ();
    603     return true;
    604 }
    605 
    606 CLImage2DArray::CLImage2DArray (
    607     const SmartPtr<CLContext> &context,
    608     const VideoBufferInfo &video_info,
    609     cl_mem_flags  flags,
    610     uint32_t extra_array_size)
    611     : CLImage (context)
    612 {
    613     CLImageDesc cl_desc;
    614 
    615     XCAM_ASSERT (video_info.components >= 2);
    616 
    617     if (!video_info_2_cl_image_desc (video_info, cl_desc)) {
    618         XCAM_LOG_WARNING ("CLVaImage create va image failed on default videoinfo");
    619         return;
    620     }
    621     XCAM_ASSERT (cl_desc.array_size >= 2);
    622 
    623     //special process for BYT platform for slice-pitch
    624     //if (video_info.format == V4L2_PIX_FMT_NV12)
    625     cl_desc.height = XCAM_ALIGN_UP (cl_desc.height, 16);
    626 
    627     cl_desc.array_size += extra_array_size;
    628 
    629     init_image_2d_array (context, cl_desc, flags);
    630 }
    631 
    632 bool CLImage2DArray::init_image_2d_array (
    633     const SmartPtr<CLContext> &context,
    634     const CLImageDesc &desc,
    635     cl_mem_flags  flags)
    636 {
    637     cl_mem mem_id = 0;
    638     cl_image_desc cl_desc;
    639 
    640     xcam_mem_clear (cl_desc);
    641     cl_desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
    642     cl_desc.image_width = desc.width;
    643     cl_desc.image_height = desc.height;
    644     cl_desc.image_depth = 1;
    645     cl_desc.image_array_size = desc.array_size;
    646     cl_desc.image_row_pitch = 0;
    647     cl_desc.image_slice_pitch = 0;
    648     cl_desc.num_mip_levels = 0;
    649     cl_desc.num_samples = 0;
    650     cl_desc.buffer = NULL;
    651 
    652     mem_id = context->create_image (flags, desc.format, cl_desc);
    653     if (mem_id == NULL) {
    654         XCAM_LOG_WARNING ("CLImage2D create image 2d failed");
    655         return false;
    656     }
    657     set_mem_id (mem_id);
    658     init_desc_by_image ();
    659     return true;
    660 }
    661 
    662 
    663 };
    664