@@ -273,42 +273,6 @@ static inline cl_platform_id _get_platform(cl_mem memobj)
273273 return _get_platform(context);
274274}
275275
276- # if defined(cl_khr_semaphore)
277-
278- static inline cl_platform_id _get_platform(cl_semaphore_khr semaphore)
279- {
280- if (semaphore == NULL) return NULL;
281-
282- cl_context context = NULL;
283- clGetSemaphoreInfoKHR(
284- semaphore,
285- CL_SEMAPHORE_CONTEXT_KHR,
286- sizeof(context),
287- &context,
288- NULL);
289- return _get_platform(context);
290- }
291-
292- # endif // defined(cl_khr_semaphore)
293-
294- # if defined(cl_intel_accelerator)
295-
296- static inline cl_platform_id _get_platform(cl_accelerator_intel accelerator)
297- {
298- if (accelerator == NULL) return NULL;
299-
300- cl_context context = NULL;
301- clGetAcceleratorInfoINTEL(
302- accelerator,
303- CL_ACCELERATOR_CONTEXT_INTEL,
304- sizeof(context),
305- &context,
306- NULL);
307- return _get_platform(context);
308- }
309-
310- # endif // defined(cl_intel_accelerator)
311-
312276/***************************************************************
313277* Function Pointer Typedefs
314278***************************************************************/
@@ -437,20 +401,54 @@ static void _init(cl_platform_id platform, openclext_dispatch_table* dispatch_pt
437401}
438402
439403# if defined(CLEXT_SINGLE_PLATFORM_ONLY)
404+
440405static openclext_dispatch_table _dispatch = {0};
441406static openclext_dispatch_table* _dispatch_ptr = NULL;
442407
443408template<typename T >
444409static inline openclext_dispatch_table* _get_dispatch(T object)
445410{
411+ if (object == NULL) return NULL;
412+
446413 if (_dispatch_ptr == NULL) {
447414 cl_platform_id platform = _get_platform(object);
448415 _init(platform, & _dispatch);
449416 _dispatch_ptr = & _dispatch;
450417 }
418+
419+ return _dispatch_ptr;
420+ }
421+
422+ // For some extension objects we cannot reliably query a platform ID without
423+ // infinitely recursing. For these objects we cannot initialize the dispatch
424+ // table if it is not already initialized.
425+
426+ # if defined(cl_khr_semaphore)
427+ template<>
428+ inline openclext_dispatch_table* _get_dispatch<cl _semaphore_khr >(cl_semaphore_khr)
429+ {
430+ return _dispatch_ptr;
431+ }
432+ # endif // defined(cl_khr_semaphore)
433+
434+ # if defined(cl_khr_command_buffer)
435+ template<>
436+ inline openclext_dispatch_table* _get_dispatch<cl _command_buffer_khr >(cl_command_buffer_khr)
437+ {
451438 return _dispatch_ptr;
452439}
440+ # endif // defined(cl_khr_command_buffer)
441+
442+ # if defined(cl_intel_accelerator)
443+ template<>
444+ inline openclext_dispatch_table* _get_dispatch<cl _accelerator_intel >(cl_accelerator_intel)
445+ {
446+ return _dispatch_ptr;
447+ }
448+ # endif // defined(cl_intel_accelerator)
449+
453450# else // defined(CLEXT_SINGLE_PLATFORM_ONLY)
451+
454452static size_t _num_platforms = 0;
455453static openclext_dispatch_table* _dispatch_array = NULL;
456454
@@ -460,6 +458,9 @@ static openclext_dispatch_table* _get_dispatch(T object)
460458 if (_num_platforms == 0 && _dispatch_array == NULL) {
461459 cl_uint numPlatforms = 0;
462460 clGetPlatformIDs(0, NULL, &numPlatforms);
461+ if (numPlatforms == 0) {
462+ return NULL;
463+ }
463464
464465 openclext_dispatch_table* dispatch =
465466 (openclext_dispatch_table*)malloc(
@@ -490,6 +491,96 @@ static openclext_dispatch_table* _get_dispatch(T object)
490491
491492 return NULL;
492493}
494+
495+ // For some extension objects we cannot reliably query a platform ID without
496+ // infinitely recursing. For these objects we cannot initialize the dispatch
497+ // table if it is not already initialized, and we need to use other methods
498+ // to find the right dispatch table.
499+
500+ # if defined(cl_khr_semaphore)
501+ template<>
502+ inline openclext_dispatch_table* _get_dispatch<cl _semaphore_khr >(cl_semaphore_khr semaphore)
503+ {
504+ if (semaphore == NULL) return NULL;
505+ if (_num_platforms <= 1) return _dispatch_array;
506+
507+ for (size_t i = 0; i < _num_platforms; i++) {
508+ openclext_dispatch_table* dispatch_ptr =
509+ _dispatch_array + i;
510+ if (dispatch_ptr->clGetSemaphoreInfoKHR) {
511+ cl_uint refCount = 0;
512+ cl_int errorCode = dispatch_ptr->clGetSemaphoreInfoKHR(
513+ semaphore,
514+ CL_SEMAPHORE_REFERENCE_COUNT_KHR,
515+ sizeof(refCount),
516+ &refCount,
517+ NULL);
518+ if (errorCode == CL_SUCCESS) {
519+ return dispatch_ptr;
520+ }
521+ }
522+ }
523+
524+ return NULL;
525+ }
526+ # endif // defined(cl_khr_semaphore)
527+
528+ # if defined(cl_khr_command_buffer)
529+ template<>
530+ inline openclext_dispatch_table* _get_dispatch<cl _command_buffer_khr >(cl_command_buffer_khr cmdbuf)
531+ {
532+ if (cmdbuf == NULL) return NULL;
533+ if (_num_platforms <= 1) return _dispatch_array;
534+
535+ for (size_t i = 0; i < _num_platforms; i++) {
536+ openclext_dispatch_table* dispatch_ptr =
537+ _dispatch_array + i;
538+ if (dispatch_ptr->clGetCommandBufferInfoKHR) {
539+ cl_uint refCount = 0;
540+ cl_int errorCode = dispatch_ptr->clGetCommandBufferInfoKHR(
541+ cmdbuf,
542+ CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR,
543+ sizeof(refCount),
544+ &refCount,
545+ NULL);
546+ if (errorCode == CL_SUCCESS) {
547+ return dispatch_ptr;
548+ }
549+ }
550+ }
551+
552+ return NULL;
553+ }
554+ # endif // defined(cl_khr_command_buffer)
555+
556+ # if defined(cl_intel_accelerator)
557+ template<>
558+ inline openclext_dispatch_table* _get_dispatch<cl _accelerator_intel >(cl_accelerator_intel accelerator)
559+ {
560+ if (accelerator == NULL) return NULL;
561+ if (_num_platforms <= 1) return _dispatch_array;
562+
563+ for (size_t i = 0; i < _num_platforms; i++) {
564+ openclext_dispatch_table* dispatch_ptr =
565+ _dispatch_array + i;
566+ if (dispatch_ptr->clGetAcceleratorInfoINTEL) {
567+ cl_uint refCount = 0;
568+ cl_int errorCode = dispatch_ptr->clGetAcceleratorInfoINTEL(
569+ accelerator,
570+ CL_ACCELERATOR_REFERENCE_COUNT_INTEL,
571+ sizeof(refCount),
572+ &refCount,
573+ NULL);
574+ if (errorCode == CL_SUCCESS) {
575+ return dispatch_ptr;
576+ }
577+ }
578+ }
579+
580+ return NULL;
581+ }
582+ # endif // defined(cl_intel_accelerator)
583+
493584# endif // defined(CLEXT_SINGLE_PLATFORM_ONLY)
494585
495586# ifdef __cplusplus
@@ -525,7 +616,13 @@ ${api.RetType} CL_API_CALL ${api.Name}(
525616% endif
526617% endfor
527618{
619+ % if api.Name == " clCreateCommandBufferKHR" :
620+ struct openclext_dispatch_table* dispatch_ptr = _get_dispatch(${ api.Params[0 ].Name} > 0 && ${ api.Params[1 ].Name} ? ${ api.Params[1 ].Name} [0] : NULL);
621+ % elif api.Name == " clEnqueueCommandBufferKHR" :
622+ struct openclext_dispatch_table* dispatch_ptr = _get_dispatch(${ api.Params[2 ].Name} );
623+ % else :
528624 struct openclext_dispatch_table* dispatch_ptr = _get_dispatch(${ api.Params[0 ].Name} );
625+ % endif
529626 if (dispatch_ptr == NULL || dispatch_ptr->${ api.Name} == NULL) {
530627% if api.RetType == " cl_int" :
531628 return CL_INVALID_OPERATION;
0 commit comments