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 #if HAVE_LIBDRM
24 #include "intel/cl_va_memory.h"
25 #endif
26 
27 namespace XCam {
28 
CLImageDesc()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
operator ==(const CLImageDesc & desc) const41 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 
CLMemory(const SmartPtr<CLContext> & context)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 
~CLMemory()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
export_fd()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
release_fd()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
enqueue_unmap(void * ptr,CLEventList & event_waits,SmartPtr<CLEvent> & event_out)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 
get_cl_mem_info(cl_image_info param_name,size_t param_size,void * param,size_t * param_size_ret)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 
CLBuffer(const SmartPtr<CLContext> & context)141 CLBuffer::CLBuffer (const SmartPtr<CLContext> &context)
142     : CLMemory (context)
143 {
144 }
145 
CLBuffer(const SmartPtr<CLContext> & context,uint32_t size,cl_mem_flags flags,void * host_ptr)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
init_buffer(const SmartPtr<CLContext> & context,uint32_t size,cl_mem_flags flags,void * host_ptr)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 
CLSubBuffer(const SmartPtr<CLContext> & context,SmartPtr<CLBuffer> main_buf,cl_mem_flags flags,uint32_t offset,uint32_t size)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
init_sub_buffer(const SmartPtr<CLContext> & context,SmartPtr<CLBuffer> main_buf,cl_mem_flags flags,uint32_t offset,uint32_t size)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
enqueue_read(void * ptr,uint32_t offset,uint32_t size,CLEventList & event_waits,SmartPtr<CLEvent> & event_out)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
enqueue_write(void * ptr,uint32_t offset,uint32_t size,CLEventList & event_waits,SmartPtr<CLEvent> & event_out)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
enqueue_map(void * & ptr,uint32_t offset,uint32_t size,cl_map_flags map_flags,CLEventList & event_waits,SmartPtr<CLEvent> & event_out)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 
CLImage(const SmartPtr<CLContext> & context)268 CLImage::CLImage (const SmartPtr<CLContext> &context)
269     : CLMemory (context)
270 {
271 }
272 
273 uint32_t
get_pixel_bytes() const274 CLImage::get_pixel_bytes () const
275 {
276     return calculate_pixel_bytes(_image_desc.format);
277 }
278 
279 bool
get_cl_image_info(cl_image_info param_name,size_t param_size,void * param,size_t * param_size_ret)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
calculate_pixel_bytes(const cl_image_format & fmt)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
video_info_2_cl_image_desc(const VideoBufferInfo & video_info,CLImageDesc & image_desc)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
init_desc_by_image()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
enqueue_map(void * & ptr,size_t * origin,size_t * region,size_t * row_pitch,size_t * slice_pitch,cl_map_flags map_flags,CLEventList & event_waits,SmartPtr<CLEvent> & event_out)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 
CLImage2D(const SmartPtr<CLContext> & context,const VideoBufferInfo & video_info,cl_mem_flags flags)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 
CLImage2D(const SmartPtr<CLContext> & context,const CLImageDesc & cl_desc,cl_mem_flags flags,SmartPtr<CLBuffer> bind_buf)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 
init_image_2d(const SmartPtr<CLContext> & context,const CLImageDesc & desc,cl_mem_flags flags)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 
CLImage2DArray(const SmartPtr<CLContext> & context,const VideoBufferInfo & video_info,cl_mem_flags flags,uint32_t extra_array_size)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 
init_image_2d_array(const SmartPtr<CLContext> & context,const CLImageDesc & desc,cl_mem_flags flags)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