• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * cl_context.cpp - CL context
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 
22 #include "cl_context.h"
23 #include "cl_kernel.h"
24 #include "cl_device.h"
25 #include <utility>
26 
27 #undef XCAM_CL_MAX_EVENT_SIZE
28 #define XCAM_CL_MAX_EVENT_SIZE 256
29 
30 #define OCL_EXT_NAME_CREATE_BUFFER_FROM_LIBVA_INTEL "clCreateBufferFromLibvaIntel"
31 #define OCL_EXT_NAME_CREATE_BUFFER_FROM_FD_INTEL    "clCreateBufferFromFdINTEL"
32 #define OCL_EXT_NAME_CREATE_IMAGE_FROM_LIBVA_INTEL  "clCreateImageFromLibvaIntel"
33 #define OCL_EXT_NAME_CREATE_IMAGE_FROM_FD_INTEL     "clCreateImageFromFdINTEL"
34 #define OCL_EXT_NAME_GET_MEM_OBJECT_FD_INTEL        "clGetMemObjectFdIntel"
35 
36 namespace XCam {
37 
38 class CLKernel;
39 
40 void
context_pfn_notify(const char * erro_info,const void * private_info,size_t cb,void * user_data)41 CLContext::context_pfn_notify (
42     const char* erro_info,
43     const void *private_info,
44     size_t cb,
45     void *user_data
46 )
47 {
48     CLContext *context = (CLContext*) user_data;
49     XCAM_UNUSED (context);
50     XCAM_UNUSED (erro_info);
51     XCAM_UNUSED (private_info);
52     XCAM_UNUSED (cb);
53     XCAM_LOG_DEBUG ("cl context pfn error:%s", XCAM_STR (erro_info));
54 }
55 
program_pfn_notify(cl_program program,void * user_data)56 void CLContext::program_pfn_notify (
57     cl_program program, void *user_data)
58 {
59     CLContext *context = (CLContext*) user_data;
60     char kernel_names [XCAM_CL_MAX_STR_SIZE];
61 
62     XCAM_UNUSED (context);
63     XCAM_UNUSED (program);
64     xcam_mem_clear (kernel_names);
65     //clGetProgramInfo (program, CL_PROGRAM_KERNEL_NAMES, sizeof (kernel_names) - 1, kernel_names, NULL);
66     //XCAM_LOG_DEBUG ("cl program report error on kernels: %s", kernel_names);
67 }
68 
69 uint32_t
event_list_2_id_array(CLEventList & events_wait,cl_event * cl_events,uint32_t max_count)70 CLContext::event_list_2_id_array (
71     CLEventList &events_wait,
72     cl_event *cl_events, uint32_t max_count)
73 {
74     uint32_t num_of_events_wait = 0;
75 
76     for (CLEventList::iterator iter = events_wait.begin ();
77             iter != events_wait.end (); ++iter) {
78         SmartPtr<CLEvent> &event = *iter;
79 
80         if (num_of_events_wait >= max_count) {
81             XCAM_LOG_WARNING ("CLEventList(%d) larger than id_array(max_count:%d)", (uint32_t)events_wait.size(), max_count);
82             break;
83         }
84         XCAM_ASSERT (event->get_event_id ());
85         cl_events[num_of_events_wait++] = event->get_event_id ();
86     }
87 
88     return num_of_events_wait;
89 }
90 
91 
CLContext(SmartPtr<CLDevice> & device)92 CLContext::CLContext (SmartPtr<CLDevice> &device)
93     : _context_id (NULL)
94     , _device (device)
95 {
96     if (!init_context ()) {
97         XCAM_LOG_ERROR ("CL init context failed");
98     }
99 
100     XCAM_LOG_DEBUG ("CLContext constructed");
101 }
102 
~CLContext()103 CLContext::~CLContext ()
104 {
105     destroy_context ();
106     XCAM_LOG_DEBUG ("CLContext destructed");
107 }
108 
109 void
terminate()110 CLContext::terminate ()
111 {
112     //_kernel_map.clear ();
113     _cmd_queue_list.clear ();
114 }
115 
116 XCamReturn
flush()117 CLContext::flush ()
118 {
119     cl_int error_code = CL_SUCCESS;
120     cl_command_queue cmd_queue_id = NULL;
121     SmartPtr<CLCommandQueue> cmd_queue = get_default_cmd_queue ();
122 
123     XCAM_ASSERT (cmd_queue.ptr ());
124     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
125     error_code = clFlush (cmd_queue_id);
126 
127     XCAM_FAIL_RETURN (
128         WARNING,
129         error_code == CL_SUCCESS,
130         XCAM_RETURN_ERROR_CL,
131         "CL flush cmdqueue failed with error_code:%d", error_code);
132 
133     return XCAM_RETURN_NO_ERROR;
134 }
135 
136 
137 XCamReturn
finish()138 CLContext::finish ()
139 {
140     cl_int error_code = CL_SUCCESS;
141     cl_command_queue cmd_queue_id = NULL;
142     SmartPtr<CLCommandQueue> cmd_queue = get_default_cmd_queue ();
143 
144     XCAM_ASSERT (cmd_queue.ptr ());
145     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
146     error_code = clFinish (cmd_queue_id);
147 
148     XCAM_FAIL_RETURN (
149         WARNING,
150         error_code == CL_SUCCESS,
151         XCAM_RETURN_ERROR_CL,
152         "CL finish cmdqueue failed with error_code:%d", error_code);
153 
154     return XCAM_RETURN_NO_ERROR;
155 }
156 
157 bool
init_context()158 CLContext::init_context ()
159 {
160     cl_context context_id = NULL;
161     cl_int err_code = 0;
162     cl_device_id device_id = _device->get_device_id ();
163 
164     XCAM_ASSERT (_context_id == NULL);
165 
166     if (!_device->is_inited()) {
167         XCAM_LOG_ERROR ("create cl context failed since device is not initialized");
168         return false;
169     }
170 
171     context_id =
172         clCreateContext (NULL, 1, &device_id,
173                          CLContext::context_pfn_notify, this,
174                          &err_code);
175     if (err_code != CL_SUCCESS)
176     {
177         XCAM_LOG_WARNING ("create cl context failed, error:%d", err_code);
178         return false;
179     }
180     _context_id = context_id;
181     return true;
182 }
183 
184 bool
init_cmd_queue(SmartPtr<CLContext> & self)185 CLContext::init_cmd_queue (SmartPtr<CLContext> &self)
186 {
187     XCAM_ASSERT (_cmd_queue_list.empty ());
188     XCAM_ASSERT (self.ptr() == this);
189     SmartPtr<CLCommandQueue> cmd_queue = create_cmd_queue (self);
190     if (!cmd_queue.ptr ())
191         return false;
192 
193     _cmd_queue_list.push_back (cmd_queue);
194     return true;
195 }
196 
197 SmartPtr<CLCommandQueue>
get_default_cmd_queue()198 CLContext::get_default_cmd_queue ()
199 {
200     CLCmdQueueList::iterator iter;
201 
202     XCAM_ASSERT (!_cmd_queue_list.empty ());
203     if (_cmd_queue_list.empty ())
204         return NULL;
205     iter = _cmd_queue_list.begin ();
206     return *iter;
207 }
208 
209 void
destroy_context()210 CLContext::destroy_context ()
211 {
212     if (!is_valid ())
213         return;
214     clReleaseContext (_context_id);
215     _context_id = NULL;
216 }
217 
218 XCamReturn
execute_kernel(const SmartPtr<CLKernel> kernel,const SmartPtr<CLCommandQueue> queue,CLEventList & events_wait,SmartPtr<CLEvent> & event_out)219 CLContext::execute_kernel (
220     const SmartPtr<CLKernel> kernel,
221     const SmartPtr<CLCommandQueue> queue,
222     CLEventList &events_wait,
223     SmartPtr<CLEvent> &event_out)
224 {
225     XCAM_ASSERT (kernel.ptr ());
226 
227     cl_int error_code = CL_SUCCESS;
228     cl_command_queue cmd_queue_id = NULL;
229     cl_event *event_out_id = NULL;
230     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
231     uint32_t num_of_events_wait = 0;
232     uint32_t work_group_size = 1;
233     const size_t *local_sizes = NULL;
234     cl_kernel kernel_id = kernel->get_kernel_id ();
235     CLWorkSize work_size = kernel->get_work_size ();
236     SmartPtr<CLCommandQueue> cmd_queue = queue;
237 
238     if (!cmd_queue.ptr ()) {
239         cmd_queue = get_default_cmd_queue ();
240     }
241     XCAM_ASSERT (cmd_queue.ptr ());
242 
243     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
244     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
245     if (event_out.ptr ())
246         event_out_id = &event_out->get_event_id ();
247 
248     for (uint32_t i = 0; i < work_size.dim; ++i) {
249         work_group_size *= work_size.local[i];
250     }
251     if (work_group_size)
252         local_sizes = work_size.local;
253     else
254         local_sizes = NULL;
255 
256     error_code =
257         clEnqueueNDRangeKernel (
258             cmd_queue_id, kernel_id,
259             work_size.dim, NULL, work_size.global, local_sizes,
260             num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
261             event_out_id);
262 
263     XCAM_FAIL_RETURN(
264         WARNING,
265         error_code == CL_SUCCESS,
266         XCAM_RETURN_ERROR_CL,
267         "execute kernel(%s) failed with error_code:%d",
268         kernel->get_kernel_name (), error_code);
269 
270     return XCAM_RETURN_NO_ERROR;
271 }
272 
273 XCamReturn
set_event_callback(SmartPtr<CLEvent> & event,cl_int status,void (* callback)(cl_event,cl_int,void *),void * user_data)274 CLContext::set_event_callback (
275     SmartPtr<CLEvent> &event, cl_int status,
276     void (*callback) (cl_event, cl_int, void*),
277     void *user_data)
278 {
279     XCAM_ASSERT (event.ptr () && event->get_event_id ());
280     cl_int error_code = clSetEventCallback (event->get_event_id (), status, callback, user_data);
281     return (error_code == CL_SUCCESS ? XCAM_RETURN_NO_ERROR : XCAM_RETURN_ERROR_CL);
282 }
283 
284 SmartPtr<CLCommandQueue>
create_cmd_queue(SmartPtr<CLContext> & self)285 CLContext::create_cmd_queue (SmartPtr<CLContext> &self)
286 {
287     cl_device_id device_id = _device->get_device_id ();
288     cl_command_queue cmd_queue_id = NULL;
289     cl_int err_code = 0;
290     SmartPtr<CLCommandQueue> result;
291 
292     XCAM_ASSERT (self.ptr() == this);
293 
294 #if defined (CL_VERSION_2_0) && (CL_VERSION_2_0 == 1)
295     cmd_queue_id = clCreateCommandQueueWithProperties (_context_id, device_id, 0, &err_code);
296 #else
297     cmd_queue_id = clCreateCommandQueue (_context_id, device_id, 0, &err_code);
298 #endif
299     if (err_code != CL_SUCCESS) {
300         XCAM_LOG_WARNING ("create CL command queue failed, errcode:%d", err_code);
301         return NULL;
302     }
303 
304     result = new CLCommandQueue (self, cmd_queue_id);
305     return result;
306 }
307 
308 cl_kernel
generate_kernel_id(CLKernel * kernel,const uint8_t * source,size_t length,CLContext::KernelBuildType type,uint8_t ** gen_binary,size_t * binary_size,const char * build_option)309 CLContext::generate_kernel_id (
310     CLKernel *kernel,
311     const uint8_t *source, size_t length,
312     CLContext::KernelBuildType type,
313     uint8_t **gen_binary, size_t *binary_size,
314     const char *build_option)
315 {
316     struct CLProgram {
317         cl_program id;
318 
319         CLProgram ()
320             : id (NULL)
321         {}
322         ~CLProgram () {
323             if (id)
324                 clReleaseProgram (id);
325         }
326     };
327 
328     CLProgram program;
329     cl_kernel kernel_id = NULL;
330     cl_int error_code = CL_SUCCESS;
331     cl_device_id device_id = _device->get_device_id ();
332     const char * name = kernel->get_kernel_name ();
333 
334     XCAM_ASSERT (source && length);
335     XCAM_ASSERT (name);
336 
337     switch (type) {
338     case KERNEL_BUILD_SOURCE:
339         program.id =
340             clCreateProgramWithSource (
341                 _context_id, 1,
342                 (const char**)(&source), (const size_t *)&length,
343                 &error_code);
344         break;
345     case KERNEL_BUILD_BINARY:
346         program.id =
347             clCreateProgramWithBinary (
348                 _context_id, 1, &device_id,
349                 (const size_t *)&length, (const uint8_t**)(&source),
350                 NULL, &error_code);
351         break;
352     }
353 
354     XCAM_FAIL_RETURN (
355         WARNING,
356         error_code == CL_SUCCESS,
357         NULL,
358         "cl create program failed with error_cod:%d", error_code);
359     XCAM_ASSERT (program.id);
360 
361     error_code = clBuildProgram (program.id, 1, &device_id, build_option, CLContext::program_pfn_notify, this);
362     if (error_code != CL_SUCCESS) {
363         //char error_log [XCAM_CL_MAX_STR_SIZE];
364         char error_log [1024 * 1024 + 32];
365         xcam_mem_clear (error_log);
366         clGetProgramBuildInfo (program.id, device_id, CL_PROGRAM_BUILD_LOG, sizeof (error_log) - 1, error_log, NULL);
367         XCAM_LOG_WARNING ("CL build program failed on %s, build log:%s", name, error_log);
368         return NULL;
369     }
370 
371     if (gen_binary != NULL && binary_size != NULL) {
372         error_code = clGetProgramInfo (program.id, CL_PROGRAM_BINARY_SIZES, sizeof (size_t) * 1, binary_size, NULL);
373         if (error_code != CL_SUCCESS) {
374             XCAM_LOG_WARNING ("CL query binary sizes failed on %s, errcode:%d", name, error_code);
375         }
376 
377         *gen_binary = (uint8_t *) xcam_malloc0 (sizeof (uint8_t) * (*binary_size));
378 
379         error_code = clGetProgramInfo (program.id, CL_PROGRAM_BINARIES, sizeof (uint8_t *) * 1, gen_binary, NULL);
380         if (error_code != CL_SUCCESS) {
381             XCAM_LOG_WARNING ("CL query program binaries failed on %s, errcode:%d", name, error_code);
382         }
383     }
384 
385     kernel_id = clCreateKernel (program.id, name, &error_code);
386     XCAM_FAIL_RETURN (
387         WARNING,
388         error_code == CL_SUCCESS,
389         NULL,
390         "cl create kernel(%s) failed with error_cod:%d", name, error_code);
391 
392     return kernel_id;
393 }
394 
395 void
destroy_kernel_id(cl_kernel & kernel_id)396 CLContext::destroy_kernel_id (cl_kernel &kernel_id)
397 {
398     if (kernel_id) {
399         clReleaseKernel (kernel_id);
400         kernel_id = NULL;
401     }
402 }
403 
404 #if 0
405 bool
406 CLContext::insert_kernel (SmartPtr<CLKernel> &kernel)
407 {
408     std::string kernel_name = kernel->get_kernel_name ();
409     CLKernelMap::iterator i_pos = _kernel_map.lower_bound (kernel_name);
410 
411     XCAM_ASSERT (!kernel_name.empty());
412     if (i_pos != _kernel_map.end () && !_kernel_map.key_comp ()(kernel_name, i_pos->first)) {
413         // need update
414         i_pos->second = kernel;
415         XCAM_LOG_DEBUG ("kernel:%s already exist in context, now update to new one", kernel_name.c_str());
416         return true;
417     }
418 
419     _kernel_map.insert (i_pos, std::make_pair (kernel_name, kernel));
420     return true;
421 }
422 #endif
423 
424 cl_mem
create_image(cl_mem_flags flags,const cl_image_format & format,const cl_image_desc & image_info,void * host_ptr)425 CLContext::create_image (
426     cl_mem_flags flags, const cl_image_format& format,
427     const cl_image_desc &image_info, void *host_ptr)
428 {
429     cl_mem mem_id = NULL;
430     cl_int errcode = CL_SUCCESS;
431 
432     mem_id = clCreateImage (
433                  _context_id, flags,
434                  &format, &image_info,
435                  host_ptr, &errcode);
436 
437     XCAM_FAIL_RETURN (
438         WARNING,
439         errcode == CL_SUCCESS,
440         NULL,
441         "create cl image failed, errcode:%d", errcode);
442     return mem_id;
443 }
444 
445 void
destroy_mem(cl_mem mem_id)446 CLContext::destroy_mem (cl_mem mem_id)
447 {
448     if (mem_id)
449         clReleaseMemObject (mem_id);
450 }
451 
452 cl_mem
create_buffer(uint32_t size,cl_mem_flags flags,void * host_ptr)453 CLContext::create_buffer (uint32_t size, cl_mem_flags flags, void *host_ptr)
454 {
455     cl_mem mem_id = NULL;
456     cl_int errcode = CL_SUCCESS;
457 
458     XCAM_ASSERT (_context_id);
459 
460     mem_id = clCreateBuffer (
461                  _context_id, flags,
462                  size, host_ptr,
463                  &errcode);
464 
465     XCAM_FAIL_RETURN (
466         WARNING,
467         errcode == CL_SUCCESS,
468         NULL,
469         "create cl buffer failed, errcode:%d", errcode);
470     return mem_id;
471 }
472 
473 cl_mem
create_sub_buffer(cl_mem main_mem,cl_buffer_region region,cl_mem_flags flags)474 CLContext::create_sub_buffer (
475     cl_mem main_mem,
476     cl_buffer_region region,
477     cl_mem_flags flags)
478 {
479     cl_mem sub_mem = NULL;
480     cl_int errcode = CL_SUCCESS;
481 
482     sub_mem = clCreateSubBuffer (main_mem, flags, CL_BUFFER_CREATE_TYPE_REGION, &region, &errcode);
483     XCAM_FAIL_RETURN (
484         WARNING,
485         errcode == CL_SUCCESS,
486         NULL,
487         "create sub buffer failed, errcode:%d", errcode);
488 
489     return sub_mem;
490 }
491 
492 XCamReturn
enqueue_read_buffer(cl_mem buf_id,void * ptr,uint32_t offset,uint32_t size,bool block,CLEventList & events_wait,SmartPtr<CLEvent> & event_out)493 CLContext::enqueue_read_buffer (
494     cl_mem buf_id, void *ptr,
495     uint32_t offset, uint32_t size,
496     bool block,
497     CLEventList &events_wait,
498     SmartPtr<CLEvent> &event_out)
499 {
500     SmartPtr<CLCommandQueue> cmd_queue;
501     cl_command_queue cmd_queue_id = NULL;
502     cl_event *event_out_id = NULL;
503     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
504     uint32_t num_of_events_wait = 0;
505     cl_int errcode = CL_SUCCESS;
506 
507     cmd_queue = get_default_cmd_queue ();
508     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
509     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
510     if (event_out.ptr ())
511         event_out_id = &event_out->get_event_id ();
512 
513     XCAM_ASSERT (_context_id);
514     XCAM_ASSERT (cmd_queue_id);
515     errcode = clEnqueueReadBuffer (
516                   cmd_queue_id, buf_id,
517                   (block ? CL_BLOCKING : CL_NON_BLOCKING),
518                   offset, size, ptr,
519                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
520                   event_out_id);
521 
522     XCAM_FAIL_RETURN (
523         WARNING,
524         errcode == CL_SUCCESS,
525         XCAM_RETURN_ERROR_CL,
526         "cl enqueue read buffer failed with error_code:%d", errcode);
527 
528     return XCAM_RETURN_NO_ERROR;
529 }
530 
531 XCamReturn
enqueue_write_buffer(cl_mem buf_id,void * ptr,uint32_t offset,uint32_t size,bool block,CLEventList & events_wait,SmartPtr<CLEvent> & event_out)532 CLContext::enqueue_write_buffer (
533     cl_mem buf_id, void *ptr,
534     uint32_t offset, uint32_t size,
535     bool block,
536     CLEventList &events_wait,
537     SmartPtr<CLEvent> &event_out)
538 {
539     SmartPtr<CLCommandQueue> cmd_queue;
540     cl_command_queue cmd_queue_id = NULL;
541     cl_event *event_out_id = NULL;
542     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
543     uint32_t num_of_events_wait = 0;
544     cl_int errcode = CL_SUCCESS;
545 
546     cmd_queue = get_default_cmd_queue ();
547     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
548     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
549     if (event_out.ptr ())
550         event_out_id = &event_out->get_event_id ();
551 
552     XCAM_ASSERT (_context_id);
553     XCAM_ASSERT (cmd_queue_id);
554     errcode = clEnqueueWriteBuffer (
555                   cmd_queue_id, buf_id,
556                   (block ? CL_BLOCKING : CL_NON_BLOCKING),
557                   offset, size, ptr,
558                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
559                   event_out_id);
560 
561     XCAM_FAIL_RETURN (
562         WARNING,
563         errcode == CL_SUCCESS,
564         XCAM_RETURN_ERROR_CL,
565         "cl enqueue write buffer failed with error_code:%d", errcode);
566 
567     return XCAM_RETURN_NO_ERROR;
568 }
569 
570 XCamReturn
enqueue_map_buffer(cl_mem buf_id,void * & ptr,uint32_t offset,uint32_t size,bool block,cl_map_flags map_flags,CLEventList & events_wait,SmartPtr<CLEvent> & event_out)571 CLContext::enqueue_map_buffer (
572     cl_mem buf_id, void *&ptr,
573     uint32_t offset, uint32_t size,
574     bool block,
575     cl_map_flags map_flags,
576     CLEventList &events_wait,
577     SmartPtr<CLEvent> &event_out)
578 {
579     SmartPtr<CLCommandQueue> cmd_queue;
580     cl_command_queue cmd_queue_id = NULL;
581     cl_event *event_out_id = NULL;
582     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
583     uint32_t num_of_events_wait = 0;
584     cl_int errcode = CL_SUCCESS;
585     void *out_ptr = NULL;
586 
587     cmd_queue = get_default_cmd_queue ();
588     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
589     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
590     if (event_out.ptr ())
591         event_out_id = &event_out->get_event_id ();
592 
593     XCAM_ASSERT (_context_id);
594     XCAM_ASSERT (cmd_queue_id);
595     out_ptr = clEnqueueMapBuffer (
596                   cmd_queue_id, buf_id,
597                   (block ? CL_BLOCKING : CL_NON_BLOCKING),
598                   map_flags,
599                   offset, size,
600                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
601                   event_out_id,
602                   &errcode);
603 
604     XCAM_FAIL_RETURN (
605         WARNING,
606         out_ptr && errcode == CL_SUCCESS,
607         XCAM_RETURN_ERROR_CL,
608         "cl enqueue map buffer failed with error_code:%d", errcode);
609 
610     ptr = out_ptr;
611     return XCAM_RETURN_NO_ERROR;
612 }
613 
614 
615 XCamReturn
enqueue_map_image(cl_mem buf_id,void * & ptr,const size_t * origin,const size_t * region,size_t * image_row_pitch,size_t * image_slice_pitch,bool block,cl_map_flags map_flags,CLEventList & events_wait,SmartPtr<CLEvent> & event_out)616 CLContext::enqueue_map_image (
617     cl_mem buf_id, void *&ptr,
618     const size_t *origin,
619     const size_t *region,
620     size_t *image_row_pitch,
621     size_t *image_slice_pitch,
622     bool block,
623     cl_map_flags map_flags,
624     CLEventList &events_wait,
625     SmartPtr<CLEvent> &event_out)
626 {
627     SmartPtr<CLCommandQueue> cmd_queue;
628     cl_command_queue cmd_queue_id = NULL;
629     cl_event *event_out_id = NULL;
630     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
631     uint32_t num_of_events_wait = 0;
632     cl_int errcode = CL_SUCCESS;
633     void *out_ptr = NULL;
634 
635     cmd_queue = get_default_cmd_queue ();
636     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
637     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
638     if (event_out.ptr ())
639         event_out_id = &event_out->get_event_id ();
640 
641     XCAM_ASSERT (_context_id);
642     XCAM_ASSERT (cmd_queue_id);
643 
644     out_ptr = clEnqueueMapImage (
645                   cmd_queue_id, buf_id,
646                   (block ? CL_BLOCKING : CL_NON_BLOCKING),
647                   map_flags,
648                   origin,
649                   region,
650                   image_row_pitch,
651                   image_slice_pitch,
652                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
653                   event_out_id,
654                   &errcode);
655 
656     XCAM_FAIL_RETURN (
657         WARNING,
658         out_ptr && errcode == CL_SUCCESS,
659         XCAM_RETURN_ERROR_CL,
660         "cl enqueue map buffer failed with error_code:%d", errcode);
661 
662     ptr = out_ptr;
663     return XCAM_RETURN_NO_ERROR;
664 }
665 
666 XCamReturn
enqueue_unmap(cl_mem mem_id,void * ptr,CLEventList & events_wait,SmartPtr<CLEvent> & event_out)667 CLContext::enqueue_unmap (
668     cl_mem mem_id,
669     void *ptr,
670     CLEventList &events_wait,
671     SmartPtr<CLEvent> &event_out)
672 {
673     SmartPtr<CLCommandQueue> cmd_queue;
674     cl_command_queue cmd_queue_id = NULL;
675     cl_event *event_out_id = NULL;
676     cl_event events_id_wait[XCAM_CL_MAX_EVENT_SIZE];
677     uint32_t num_of_events_wait = 0;
678     cl_int errcode = CL_SUCCESS;
679 
680     cmd_queue = get_default_cmd_queue ();
681     cmd_queue_id = cmd_queue->get_cmd_queue_id ();
682     num_of_events_wait = event_list_2_id_array (events_wait, events_id_wait, XCAM_CL_MAX_EVENT_SIZE);
683     if (event_out.ptr ())
684         event_out_id = &event_out->get_event_id ();
685 
686     XCAM_ASSERT (_context_id);
687     XCAM_ASSERT (cmd_queue_id);
688     errcode = clEnqueueUnmapMemObject (
689                   cmd_queue_id, mem_id, ptr,
690                   num_of_events_wait, (num_of_events_wait ? events_id_wait : NULL),
691                   event_out_id);
692 
693     XCAM_FAIL_RETURN (
694         WARNING,
695         errcode == CL_SUCCESS,
696         XCAM_RETURN_ERROR_CL,
697         "cl enqueue unmap buffer failed with error_code:%d", errcode);
698 
699     return XCAM_RETURN_NO_ERROR;
700 }
701 
CLCommandQueue(SmartPtr<CLContext> & context,cl_command_queue id)702 CLCommandQueue::CLCommandQueue (SmartPtr<CLContext> &context, cl_command_queue id)
703     : _context (context)
704     , _cmd_queue_id (id)
705 {
706     XCAM_ASSERT (context.ptr ());
707     XCAM_ASSERT (id);
708     XCAM_LOG_DEBUG ("CLCommandQueue constructed");
709 }
710 
~CLCommandQueue()711 CLCommandQueue::~CLCommandQueue ()
712 {
713     destroy ();
714     XCAM_LOG_DEBUG ("CLCommandQueue desstructed");
715 }
716 
717 void
destroy()718 CLCommandQueue::destroy ()
719 {
720     if (_cmd_queue_id == NULL)
721         return;
722 
723     clReleaseCommandQueue (_cmd_queue_id);
724     _cmd_queue_id = NULL;
725 }
726 
727 };
728