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, ®ion, &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