cl_memory.cpp revision cff638b59385036cbc91873a9965282c8861a306
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@intel.com>
19 */
20
21#include "cl_utils.h"
22#include "cl_memory.h"
23#include "drm_display.h"
24#include "cl_image_bo_buffer.h"
25
26namespace XCam {
27
28CLImageDesc::CLImageDesc ()
29    : format {CL_R, CL_UNORM_INT8}
30, width (0)
31, height (0)
32, row_pitch (0)
33, slice_pitch (0)
34, array_size (0)
35, size (0)
36{
37}
38
39bool
40CLImageDesc::operator == (const CLImageDesc& desc) const
41{
42    if (desc.format.image_channel_data_type == this->format.image_channel_data_type &&
43            desc.format.image_channel_order == this->format.image_channel_order &&
44            desc.width == this->width &&
45            desc.height == this->height &&
46            desc.row_pitch == this->row_pitch &&
47            desc.slice_pitch == this->slice_pitch &&
48            desc.array_size == this->array_size)// &&
49        //desc.size == this->size)
50        return true;
51    return false;
52}
53
54CLMemory::CLMemory (const SmartPtr<CLContext> &context)
55    : _context (context)
56    , _mem_id (NULL)
57    , _mem_fd (-1)
58    , _mem_need_destroy (true)
59    , _mapped_ptr (NULL)
60{
61    XCAM_ASSERT (context.ptr () && context->is_valid ());
62}
63
64CLMemory::~CLMemory ()
65{
66    release_fd ();
67
68    if (_mapped_ptr)
69        enqueue_unmap (_mapped_ptr);
70
71    if (_mem_id && _mem_need_destroy) {
72        _context->destroy_mem (_mem_id);
73    }
74}
75
76int32_t
77CLMemory::export_fd ()
78{
79    if (_mem_fd >= 0)
80        return _mem_fd;
81
82    _mem_fd = _context->export_mem_fd (_mem_id);
83    return _mem_fd;
84}
85
86void
87CLMemory::release_fd ()
88{
89    if (_mem_fd <= 0)
90        return;
91
92    close (_mem_fd);
93    _mem_fd = -1;
94}
95
96XCamReturn
97CLMemory::enqueue_unmap (
98    void *ptr,
99    CLEventList &event_waits,
100    SmartPtr<CLEvent> &event_out)
101{
102    SmartPtr<CLContext> context = get_context ();
103    cl_mem mem_id = get_mem_id ();
104
105    XCAM_ASSERT (is_valid ());
106    if (!is_valid ())
107        return XCAM_RETURN_ERROR_PARAM;
108
109    XCAM_ASSERT (ptr == _mapped_ptr);
110    if (ptr == _mapped_ptr)
111        _mapped_ptr = NULL;
112
113    return context->enqueue_unmap (mem_id, ptr, event_waits, event_out);
114}
115
116bool CLMemory::get_cl_mem_info (
117    cl_image_info param_name, size_t param_size,
118    void *param, size_t *param_size_ret)
119{
120    cl_mem mem_id = get_mem_id ();
121    cl_int error_code = CL_SUCCESS;
122    if (!mem_id)
123        return false;
124
125    error_code = clGetMemObjectInfo (mem_id, param_name, param_size, param, param_size_ret);
126    XCAM_FAIL_RETURN(
127        WARNING,
128        error_code == CL_SUCCESS,
129        false,
130        "clGetMemObjectInfo failed on param:%d, errno:%d", param_name, error_code);
131    return true;
132}
133
134CLBuffer::CLBuffer (const SmartPtr<CLContext> &context)
135    : CLMemory (context)
136{
137}
138
139CLBuffer::CLBuffer (
140    const SmartPtr<CLContext> &context, uint32_t size,
141    cl_mem_flags  flags, void *host_ptr)
142    : CLMemory (context)
143    , _flags (flags)
144    , _size (size)
145{
146    init_buffer (context, size, flags, host_ptr);
147}
148
149bool
150CLBuffer::init_buffer (
151    const SmartPtr<CLContext> &context, uint32_t size,
152    cl_mem_flags  flags, void *host_ptr)
153{
154    cl_mem mem_id = NULL;
155
156    mem_id = context->create_buffer (size, flags, host_ptr);
157    if (mem_id == NULL) {
158        XCAM_LOG_WARNING ("CLBuffer create buffer failed");
159        return false;
160    }
161
162    set_mem_id (mem_id);
163    return true;
164}
165
166CLSubBuffer::CLSubBuffer (
167    const SmartPtr<CLContext> &context, SmartPtr<CLBuffer> main_buf,
168    cl_mem_flags flags, uint32_t offset, uint32_t size)
169    : CLBuffer (context)
170    , _main_buf (main_buf)
171    , _flags (flags)
172    , _size (size)
173{
174    init_sub_buffer (context, main_buf, flags, offset, size);
175}
176
177bool
178CLSubBuffer::init_sub_buffer (
179    const SmartPtr<CLContext> &context,
180    SmartPtr<CLBuffer> main_buf,
181    cl_mem_flags flags,
182    uint32_t offset,
183    uint32_t size)
184{
185    cl_mem sub_mem = NULL;
186    cl_mem main_mem = main_buf->get_mem_id ();
187    XCAM_FAIL_RETURN (ERROR, main_mem != NULL, false, "get memory from main image failed");
188
189    cl_buffer_region region;
190    region.origin = offset;
191    region.size = size;
192
193    sub_mem = context->create_sub_buffer (main_mem, region, flags);
194    if (sub_mem == NULL) {
195        XCAM_LOG_WARNING ("CLBuffer create sub buffer failed");
196        return false;
197    }
198
199    set_mem_id (sub_mem);
200    return true;
201}
202
203XCamReturn
204CLBuffer::enqueue_read (
205    void *ptr, uint32_t offset, uint32_t size,
206    CLEventList &event_waits,
207    SmartPtr<CLEvent> &event_out)
208{
209    SmartPtr<CLContext> context = get_context ();
210    cl_mem mem_id = get_mem_id ();
211
212    XCAM_ASSERT (is_valid ());
213    if (!is_valid ())
214        return XCAM_RETURN_ERROR_PARAM;
215
216    return context->enqueue_read_buffer (mem_id, ptr, offset, size, true, event_waits, event_out);
217}
218
219XCamReturn
220CLBuffer::enqueue_write (
221    void *ptr, uint32_t offset, uint32_t size,
222    CLEventList &event_waits,
223    SmartPtr<CLEvent> &event_out)
224{
225    SmartPtr<CLContext> context = get_context ();
226    cl_mem mem_id = get_mem_id ();
227
228    XCAM_ASSERT (is_valid ());
229    if (!is_valid ())
230        return XCAM_RETURN_ERROR_PARAM;
231
232    return context->enqueue_write_buffer (mem_id, ptr, offset, size, true, event_waits, event_out);
233}
234
235XCamReturn
236CLBuffer::enqueue_map (
237    void *&ptr, uint32_t offset, uint32_t size,
238    cl_map_flags map_flags,
239    CLEventList &event_waits,
240    SmartPtr<CLEvent> &event_out)
241{
242    SmartPtr<CLContext> context = get_context ();
243    cl_mem mem_id = get_mem_id ();
244    XCamReturn ret = XCAM_RETURN_NO_ERROR;
245
246    XCAM_ASSERT (is_valid ());
247    if (!is_valid ())
248        return XCAM_RETURN_ERROR_PARAM;
249
250    ret = context->enqueue_map_buffer (mem_id, ptr, offset, size, true, map_flags, event_waits, event_out);
251    XCAM_FAIL_RETURN (
252        WARNING,
253        ret == XCAM_RETURN_NO_ERROR,
254        ret,
255        "enqueue_map failed ");
256
257    set_mapped_ptr (ptr);
258    return ret;
259}
260
261CLVaBuffer::CLVaBuffer (
262    const SmartPtr<CLContext> &context,
263    SmartPtr<DrmBoBuffer> &bo)
264    : CLBuffer (context)
265    , _bo (bo)
266{
267    init_va_buffer (context, bo);
268}
269
270bool
271CLVaBuffer::init_va_buffer (const SmartPtr<CLContext> &context, SmartPtr<DrmBoBuffer> &bo)
272{
273    cl_mem mem_id = NULL;
274    uint32_t bo_name = 0;
275    cl_import_buffer_info_intel import_buffer_info;
276
277    xcam_mem_clear (import_buffer_info);
278    import_buffer_info.fd = bo->get_fd ();
279    import_buffer_info.size = bo->get_size ();
280    if (import_buffer_info.fd != -1) {
281        mem_id = context->import_dma_buffer (import_buffer_info);
282    }
283
284    if (mem_id == NULL) {
285        drm_intel_bo_flink (bo->get_bo (), &bo_name);
286        mem_id = context->create_va_buffer (bo_name);
287        if (mem_id == NULL) {
288            XCAM_LOG_WARNING ("CLVaBuffer create va buffer failed");
289            return false;
290        }
291    }
292
293    set_mem_id (mem_id);
294    return true;
295}
296
297CLImage::CLImage (const SmartPtr<CLContext> &context)
298    : CLMemory (context)
299{
300}
301
302uint32_t
303CLImage::get_pixel_bytes () const
304{
305    return calculate_pixel_bytes(_image_desc.format);
306}
307
308bool
309CLImage::get_cl_image_info (cl_image_info param_name, size_t param_size, void *param, size_t *param_size_ret)
310{
311    cl_mem mem_id = get_mem_id ();
312    cl_int error_code = CL_SUCCESS;
313    if (!mem_id)
314        return false;
315
316    error_code = clGetImageInfo (mem_id, param_name, param_size, param, param_size_ret);
317    XCAM_FAIL_RETURN(
318        WARNING,
319        error_code == CL_SUCCESS,
320        false,
321        "clGetImageInfo failed on param:%d, errno:%d", param_name, error_code);
322    return true;
323}
324
325uint32_t
326CLImage::calculate_pixel_bytes (const cl_image_format &fmt)
327{
328    uint32_t a = 0, b = 0;
329    switch (fmt.image_channel_order) {
330    case CL_R:
331    case CL_A:
332    case CL_Rx:
333        a = 1;
334        break;
335    case CL_RG:
336    case CL_RA:
337    case CL_RGx:
338        a = 2;
339        break;
340    case CL_RGB:
341    case CL_RGBx:
342        a = 3;
343        break;
344    case CL_RGBA:
345    case CL_BGRA:
346    case CL_ARGB:
347        a = 4;
348        break;
349    default:
350        XCAM_LOG_DEBUG ("calculate_pixel_bytes with wrong channel_order:0x%04x", fmt.image_channel_order);
351        return 0;
352    }
353
354    switch (fmt.image_channel_data_type) {
355    case CL_UNORM_INT8:
356    case CL_SNORM_INT8:
357    case CL_SIGNED_INT8:
358    case CL_UNSIGNED_INT8:
359        b = 1;
360        break;
361    case CL_SNORM_INT16:
362    case CL_UNORM_INT16:
363    case CL_SIGNED_INT16:
364    case CL_UNSIGNED_INT16:
365    case CL_HALF_FLOAT:
366        b = 2;
367        break;
368    case CL_UNORM_INT24:
369        b = 3;
370        break;
371    case CL_SIGNED_INT32:
372    case CL_UNSIGNED_INT32:
373    case CL_FLOAT:
374        b = 4;
375        break;
376    default:
377        XCAM_LOG_DEBUG ("calculate_pixel_bytes with wrong channel_data_type:0x%04x", fmt.image_channel_data_type);
378        return 0;
379    }
380
381    return a * b;
382}
383
384bool
385CLImage::video_info_2_cl_image_desc (
386    const VideoBufferInfo & video_info,
387    CLImageDesc &image_desc)
388{
389    image_desc.width = video_info.width;
390    image_desc.height = video_info.height;
391    image_desc.array_size = 0;
392    image_desc.row_pitch = video_info.strides[0];
393    XCAM_ASSERT (image_desc.row_pitch >= image_desc.width);
394    image_desc.slice_pitch = 0;
395
396    switch (video_info.format) {
397    case XCAM_PIX_FMT_RGB48:
398        //cl_image_info.fmt.image_channel_order = CL_RGB;
399        //cl_image_info.fmt.image_channel_data_type = CL_UNORM_INT16;
400        XCAM_LOG_WARNING (
401            "video_info to cl_image_info doesn't support XCAM_PIX_FMT_RGB48, maybe try XCAM_PIX_FMT_RGBA64 instread\n"
402            " **** XCAM_PIX_FMT_RGB48 need check with cl implementation ****");
403        return false;
404        break;
405    case V4L2_PIX_FMT_GREY:
406        image_desc.format.image_channel_order = CL_R;
407        image_desc.format.image_channel_data_type = CL_UNORM_INT8;
408        break;
409
410    case XCAM_PIX_FMT_RGBA64:
411        image_desc.format.image_channel_order = CL_RGBA;
412        image_desc.format.image_channel_data_type = CL_UNORM_INT16;
413        break;
414
415    case V4L2_PIX_FMT_RGB24:
416        image_desc.format.image_channel_order = CL_RGB;
417        image_desc.format.image_channel_data_type = CL_UNORM_INT8;
418        break;
419
420    case V4L2_PIX_FMT_RGB565:
421        image_desc.format.image_channel_order = CL_RGB;
422        image_desc.format.image_channel_data_type = CL_UNORM_SHORT_565;
423        break;
424    case V4L2_PIX_FMT_XBGR32:
425    case V4L2_PIX_FMT_ABGR32:
426    case V4L2_PIX_FMT_BGR32:
427        image_desc.format.image_channel_order = CL_BGRA;
428        image_desc.format.image_channel_data_type = CL_UNORM_INT8;
429        break;
430        // cl doesn'tn support ARGB32 up to now, how about consider V4L2_PIX_FMT_RGBA32
431    case V4L2_PIX_FMT_RGB32:
432    case V4L2_PIX_FMT_ARGB32:
433    case V4L2_PIX_FMT_XRGB32:
434        image_desc.format.image_channel_order = CL_ARGB;
435        image_desc.format.image_channel_data_type = CL_UNORM_INT8;
436        break;
437
438    case V4L2_PIX_FMT_RGBA32:
439        image_desc.format.image_channel_order = CL_RGBA;
440        image_desc.format.image_channel_data_type = CL_UNORM_INT8;
441        break;
442
443    case V4L2_PIX_FMT_SBGGR10:
444    case V4L2_PIX_FMT_SGBRG10:
445    case V4L2_PIX_FMT_SGRBG10:
446    case V4L2_PIX_FMT_SRGGB10:
447    case V4L2_PIX_FMT_SBGGR12:
448    case V4L2_PIX_FMT_SGBRG12:
449    case V4L2_PIX_FMT_SGRBG12:
450    case V4L2_PIX_FMT_SRGGB12:
451    case V4L2_PIX_FMT_SBGGR16:
452    case XCAM_PIX_FMT_SGRBG16:
453        image_desc.format.image_channel_order = CL_R;
454        image_desc.format.image_channel_data_type = CL_UNORM_INT16;
455        break;
456
457    case V4L2_PIX_FMT_SBGGR8:
458    case V4L2_PIX_FMT_SGBRG8:
459    case V4L2_PIX_FMT_SGRBG8:
460    case V4L2_PIX_FMT_SRGGB8:
461        image_desc.format.image_channel_order = CL_R;
462        image_desc.format.image_channel_data_type = CL_UNORM_INT8;
463        break;
464
465    case V4L2_PIX_FMT_NV12:
466        image_desc.format.image_channel_order = CL_R;
467        image_desc.format.image_channel_data_type = CL_UNORM_INT8;
468        image_desc.array_size = 2;
469        image_desc.slice_pitch = video_info.strides [0] * video_info.aligned_height;
470        break;
471
472    case V4L2_PIX_FMT_YUYV:
473        image_desc.format.image_channel_order = CL_RGBA;
474        image_desc.format.image_channel_data_type = CL_UNORM_INT8;
475        image_desc.width /= 2;
476        break;
477
478    case XCAM_PIX_FMT_LAB:
479        image_desc.format.image_channel_order = CL_R;
480        image_desc.format.image_channel_data_type = CL_FLOAT;
481        break;
482
483    case XCAM_PIX_FMT_RGB48_planar:
484    case XCAM_PIX_FMT_RGB24_planar:
485        image_desc.format.image_channel_order = CL_RGBA;
486        if (XCAM_PIX_FMT_RGB48_planar == video_info.format)
487            image_desc.format.image_channel_data_type = CL_UNORM_INT16;
488        else
489            image_desc.format.image_channel_data_type = CL_UNORM_INT8;
490        image_desc.width = video_info.aligned_width / 4;
491        image_desc.array_size = 3;
492        image_desc.slice_pitch = video_info.strides [0] * video_info.aligned_height;
493        break;
494
495    case XCAM_PIX_FMT_SGRBG16_planar:
496    case XCAM_PIX_FMT_SGRBG8_planar:
497        image_desc.format.image_channel_order = CL_RGBA;
498        if (XCAM_PIX_FMT_SGRBG16_planar == video_info.format)
499            image_desc.format.image_channel_data_type = CL_UNORM_INT16;
500        else
501            image_desc.format.image_channel_data_type = CL_UNORM_INT8;
502        image_desc.width = video_info.aligned_width / 4;
503        image_desc.array_size = 4;
504        image_desc.slice_pitch = video_info.strides [0] * video_info.aligned_height;
505        break;
506
507    default:
508        XCAM_LOG_WARNING (
509            "video_info to cl_image_info doesn't support format:%s",
510            xcam_fourcc_to_string (video_info.format));
511        return false;
512    }
513
514    return true;
515}
516
517void
518CLImage::init_desc_by_image ()
519{
520    size_t width = 0, height = 0, row_pitch = 0, slice_pitch = 0, array_size = 0, mem_size = 0;
521    cl_image_format format = {CL_R, CL_UNORM_INT8};
522
523    get_cl_image_info (CL_IMAGE_FORMAT, sizeof(format), &format);
524    get_cl_image_info (CL_IMAGE_WIDTH, sizeof(width), &width);
525    get_cl_image_info (CL_IMAGE_HEIGHT, sizeof(height), &height);
526    get_cl_image_info (CL_IMAGE_ROW_PITCH, sizeof(row_pitch), &row_pitch);
527    get_cl_image_info (CL_IMAGE_SLICE_PITCH, sizeof(slice_pitch), &slice_pitch);
528    get_cl_image_info (CL_IMAGE_ARRAY_SIZE, sizeof(array_size), &array_size);
529    get_cl_mem_info (CL_MEM_SIZE, sizeof(mem_size), &mem_size);
530
531    _image_desc.format = format;
532    _image_desc.width = width;
533    _image_desc.height = height;
534    _image_desc.row_pitch = row_pitch;
535    _image_desc.slice_pitch = slice_pitch;
536    _image_desc.array_size = array_size;
537    _image_desc.size = mem_size;
538}
539
540XCamReturn
541CLImage::enqueue_map (
542    void *&ptr,
543    size_t *origin, size_t *region,
544    size_t *row_pitch, size_t *slice_pitch,
545    cl_map_flags map_flags,
546    CLEventList &event_waits,
547    SmartPtr<CLEvent> &event_out)
548{
549    SmartPtr<CLContext> context = get_context ();
550    cl_mem mem_id = get_mem_id ();
551    XCamReturn ret = XCAM_RETURN_NO_ERROR;
552
553    XCAM_ASSERT (is_valid ());
554    if (!is_valid ())
555        return XCAM_RETURN_ERROR_PARAM;
556
557    ret = context->enqueue_map_image (mem_id, ptr, origin, region, row_pitch, slice_pitch, true, map_flags, event_waits, event_out);
558    XCAM_FAIL_RETURN (
559        WARNING,
560        ret == XCAM_RETURN_NO_ERROR,
561        ret,
562        "enqueue_map failed ");
563
564    set_mapped_ptr (ptr);
565    return ret;
566}
567
568CLVaImage::CLVaImage (
569    const SmartPtr<CLContext> &context,
570    SmartPtr<DrmBoBuffer> &bo,
571    uint32_t offset,
572    bool single_plane)
573    : CLImage (context)
574    , _bo (bo)
575{
576    CLImageDesc cl_desc;
577
578    const VideoBufferInfo & video_info = bo->get_video_info ();
579    if (!video_info_2_cl_image_desc (video_info, cl_desc)) {
580        XCAM_LOG_WARNING ("CLVaImage create va image failed on default videoinfo");
581        return;
582    }
583    if (single_plane) {
584        cl_desc.array_size = 0;
585        cl_desc.slice_pitch = 0;
586    } else if (!merge_multi_plane (video_info, cl_desc)) {
587        XCAM_LOG_WARNING ("CLVaImage create va image failed on merging planes");
588        return;
589    }
590
591    init_va_image (context, bo, cl_desc, offset);
592}
593
594CLVaImage::CLVaImage (
595    const SmartPtr<CLContext> &context,
596    SmartPtr<DrmBoBuffer> &bo,
597    const CLImageDesc &image_info,
598    uint32_t offset)
599    : CLImage (context)
600    , _bo (bo)
601{
602    init_va_image (context, bo, image_info, offset);
603}
604
605bool
606CLVaImage::merge_multi_plane (
607    const VideoBufferInfo &video_info,
608    CLImageDesc &cl_desc)
609{
610    if (cl_desc.array_size <= 1)
611        return true;
612
613    switch (video_info.format) {
614    case V4L2_PIX_FMT_NV12:
615        cl_desc.height = video_info.aligned_height + video_info.height / 2;
616        break;
617
618    case XCAM_PIX_FMT_RGB48_planar:
619    case XCAM_PIX_FMT_RGB24_planar:
620        cl_desc.height = video_info.aligned_height * 3;
621        break;
622
623    case XCAM_PIX_FMT_SGRBG16_planar:
624    case XCAM_PIX_FMT_SGRBG8_planar:
625        cl_desc.height = video_info.aligned_height * 4;
626        break;
627
628    default:
629        XCAM_LOG_WARNING ("CLVaImage unknown format(%s) plane change", xcam_fourcc_to_string(video_info.format));
630        return false;
631    }
632    cl_desc.array_size = 0;
633    cl_desc.slice_pitch = 0;
634    return true;
635}
636
637bool
638CLVaImage::init_va_image (
639    const SmartPtr<CLContext> &context, SmartPtr<DrmBoBuffer> &bo,
640    const CLImageDesc &cl_desc, uint32_t offset)
641{
642
643    uint32_t bo_name = 0;
644    cl_mem mem_id = 0;
645    bool need_create = true;
646    cl_libva_image va_image_info;
647    cl_import_image_info_intel import_image_info;
648
649    xcam_mem_clear (va_image_info);
650    xcam_mem_clear (import_image_info);
651    import_image_info.offset = va_image_info.offset = offset;
652    import_image_info.width = va_image_info.width = cl_desc.width;
653    import_image_info.height = va_image_info.height = cl_desc.height;
654    import_image_info.fmt = va_image_info.fmt = cl_desc.format;
655    import_image_info.row_pitch = va_image_info.row_pitch = cl_desc.row_pitch;
656    import_image_info.size = cl_desc.size;
657    import_image_info.type = CL_MEM_OBJECT_IMAGE2D;
658
659    XCAM_ASSERT (bo.ptr ());
660
661    SmartPtr<CLImageBoBuffer> cl_image_buffer = bo.dynamic_cast_ptr<CLImageBoBuffer> ();
662    if (cl_image_buffer.ptr ()) {
663        SmartPtr<CLImage> cl_image_data = cl_image_buffer->get_cl_image ();
664        XCAM_ASSERT (cl_image_data.ptr ());
665        CLImageDesc old_desc = cl_image_data->get_image_desc ();
666        if (cl_desc == old_desc) {
667            need_create = false;
668            mem_id = cl_image_data->get_mem_id ();
669        }
670    }
671
672    if (need_create) {
673        import_image_info.fd = bo->get_fd();
674        if (import_image_info.fd != -1)
675            mem_id = context->import_dma_image (import_image_info);
676
677        if (mem_id == NULL) {
678            if (drm_intel_bo_flink (bo->get_bo (), &bo_name) == 0) {
679                va_image_info.bo_name = bo_name;
680                mem_id = context->create_va_image (va_image_info);
681            }
682            if (mem_id == NULL) {
683                XCAM_LOG_WARNING ("create va image failed");
684                return false;
685            }
686        }
687    } else {
688        va_image_info.bo_name = uint32_t(-1);
689    }
690
691    set_mem_id (mem_id, need_create);
692    init_desc_by_image ();
693    _va_image_info = va_image_info;
694    return true;
695}
696
697
698CLImage2D::CLImage2D (
699    const SmartPtr<CLContext> &context,
700    const VideoBufferInfo &video_info,
701    cl_mem_flags  flags)
702    : CLImage (context)
703{
704    CLImageDesc cl_desc;
705
706    if (!video_info_2_cl_image_desc (video_info, cl_desc)) {
707        XCAM_LOG_WARNING ("CLVaImage create va image failed on default videoinfo");
708        return;
709    }
710
711    init_image_2d (context, cl_desc, flags);
712}
713
714CLImage2D::CLImage2D (
715    const SmartPtr<CLContext> &context,
716    const CLImageDesc &cl_desc,
717    cl_mem_flags  flags,
718    SmartPtr<CLBuffer> bind_buf)
719    : CLImage (context)
720{
721    _bind_buf = bind_buf;
722    init_image_2d (context, cl_desc, flags);
723}
724
725bool CLImage2D::init_image_2d (
726    const SmartPtr<CLContext> &context,
727    const CLImageDesc &desc,
728    cl_mem_flags  flags)
729{
730    cl_mem mem_id = 0;
731    cl_image_desc cl_desc;
732
733    xcam_mem_clear (cl_desc);
734    cl_desc.image_type = CL_MEM_OBJECT_IMAGE2D;
735    cl_desc.image_width = desc.width;
736    cl_desc.image_height = desc.height;
737    cl_desc.image_depth = 1;
738    cl_desc.image_array_size = 0;
739    cl_desc.image_row_pitch = 0;
740    cl_desc.image_slice_pitch = 0;
741    cl_desc.num_mip_levels = 0;
742    cl_desc.num_samples = 0;
743    cl_desc.buffer = NULL;
744    if (_bind_buf.ptr ()) {
745        if (desc.row_pitch)
746            cl_desc.image_row_pitch = desc.row_pitch;
747        else {
748            cl_desc.image_row_pitch = calculate_pixel_bytes(desc.format) * desc.width;
749        }
750        XCAM_ASSERT (cl_desc.image_row_pitch);
751        cl_desc.buffer = _bind_buf->get_mem_id ();
752        XCAM_ASSERT (cl_desc.buffer);
753    }
754
755    mem_id = context->create_image (flags, desc.format, cl_desc);
756    if (mem_id == NULL) {
757        XCAM_LOG_WARNING ("CLImage2D create image 2d failed");
758        return false;
759    }
760    set_mem_id (mem_id);
761    init_desc_by_image ();
762    return true;
763}
764
765CLImage2DArray::CLImage2DArray (
766    const SmartPtr<CLContext> &context,
767    const VideoBufferInfo &video_info,
768    cl_mem_flags  flags,
769    uint32_t extra_array_size)
770    : CLImage (context)
771{
772    CLImageDesc cl_desc;
773
774    XCAM_ASSERT (video_info.components >= 2);
775
776    if (!video_info_2_cl_image_desc (video_info, cl_desc)) {
777        XCAM_LOG_WARNING ("CLVaImage create va image failed on default videoinfo");
778        return;
779    }
780    XCAM_ASSERT (cl_desc.array_size >= 2);
781
782    //special process for BYT platform for slice-pitch
783    //if (video_info.format == V4L2_PIX_FMT_NV12)
784    cl_desc.height = XCAM_ALIGN_UP (cl_desc.height, 16);
785
786    cl_desc.array_size += extra_array_size;
787
788    init_image_2d_array (context, cl_desc, flags);
789}
790
791bool CLImage2DArray::init_image_2d_array (
792    const SmartPtr<CLContext> &context,
793    const CLImageDesc &desc,
794    cl_mem_flags  flags)
795{
796    cl_mem mem_id = 0;
797    cl_image_desc cl_desc;
798
799    xcam_mem_clear (cl_desc);
800    cl_desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
801    cl_desc.image_width = desc.width;
802    cl_desc.image_height = desc.height;
803    cl_desc.image_depth = 1;
804    cl_desc.image_array_size = desc.array_size;
805    cl_desc.image_row_pitch = 0;
806    cl_desc.image_slice_pitch = 0;
807    cl_desc.num_mip_levels = 0;
808    cl_desc.num_samples = 0;
809    cl_desc.buffer = NULL;
810
811    mem_id = context->create_image (flags, desc.format, cl_desc);
812    if (mem_id == NULL) {
813        XCAM_LOG_WARNING ("CLImage2D create image 2d failed");
814        return false;
815    }
816    set_mem_id (mem_id);
817    init_desc_by_image ();
818    return true;
819}
820
821
822};
823