| /* |
| * cl_device.cpp - CL device |
| * |
| * Copyright (c) 2015 Intel Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * Author: Wind Yuan <[email protected]> |
| */ |
| |
| #include "cl_device.h" |
| #include "cl_context.h" |
| #if HAVE_LIBDRM |
| #include "intel/cl_intel_context.h" |
| #endif |
| |
| namespace XCam { |
| |
| SmartPtr<CLDevice> CLDevice::_instance; |
| Mutex CLDevice::_instance_mutex; |
| |
| SmartPtr<CLDevice> |
| CLDevice::instance () |
| { |
| SmartLock locker(_instance_mutex); |
| if (_instance.ptr()) |
| return _instance; |
| |
| _instance = new CLDevice (); |
| // create default context |
| if (_instance->is_inited() && |
| !_instance->create_default_context ()) { |
| XCAM_LOG_WARNING ("CL device create default context failed"); |
| } |
| |
| return _instance; |
| } |
| |
| CLDevice::CLDevice() |
| : _platform_id (NULL) |
| , _device_id (NULL) |
| , _inited (false) |
| { |
| if (!init()) { |
| XCAM_LOG_WARNING ("CL device init failed"); |
| } |
| XCAM_LOG_DEBUG ("CL device constructed"); |
| } |
| |
| CLDevice::~CLDevice () |
| { |
| XCAM_LOG_DEBUG ("CL device destructed"); |
| } |
| |
| SmartPtr<CLContext> |
| CLDevice::get_context () |
| { |
| //created in CLDevice construction |
| return _default_context; |
| } |
| |
| void * |
| CLDevice::get_extension_function (const char *func_name) |
| { |
| XCAM_ASSERT (func_name); |
| void *ext_func = NULL; |
| |
| #if defined (CL_VERSION_1_2) && (CL_VERSION_1_2 == 1) |
| ext_func = (void *) clGetExtensionFunctionAddressForPlatform (_platform_id, func_name); |
| #else |
| ext_func = (void *) clGetExtensionFunctionAddress (func_name); |
| #endif |
| if (!ext_func) |
| XCAM_LOG_ERROR ("ocl driver get extension function (%s) failed", func_name); |
| |
| return ext_func; |
| } |
| |
| void |
| CLDevice::terminate () |
| { |
| if (_default_context.ptr ()) { |
| _default_context->terminate (); |
| _default_context.release (); |
| } |
| } |
| |
| bool |
| CLDevice::init () |
| { |
| cl_platform_id platform_id = NULL; |
| cl_device_id device_id = NULL; |
| cl_uint num_platform = 0; |
| cl_uint num_device = 0; |
| CLDevieInfo device_info; |
| |
| if (clGetPlatformIDs (1, &platform_id, &num_platform) != CL_SUCCESS) |
| { |
| XCAM_LOG_WARNING ("get cl platform ID failed"); |
| return false; |
| } |
| XCAM_ASSERT (num_platform >= 1); |
| |
| if (clGetDeviceIDs (platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, &num_device) != CL_SUCCESS) |
| { |
| XCAM_LOG_WARNING ("get cl device ID failed"); |
| return false; |
| } |
| XCAM_ASSERT (num_device >= 1); |
| |
| // only query first device info |
| if (!query_device_info (device_id, device_info)) { |
| //continue |
| XCAM_LOG_WARNING ("cl get device info failed but continue"); |
| } else { |
| XCAM_LOG_INFO ( |
| "cl get device info,\n" |
| "\tmax_compute_unit:%" PRIu32 |
| "\tmax_work_item_dims:%" PRIu32 |
| "\tmax_work_item_sizes:{%" PRIuS ", %" PRIuS ", %" PRIuS "}" |
| "\tmax_work_group_size:%" PRIuS |
| "\timage_pitch_alignment:%" PRIu32, |
| device_info.max_compute_unit, |
| device_info.max_work_item_dims, |
| device_info.max_work_item_sizes[0], device_info.max_work_item_sizes[1], device_info.max_work_item_sizes[2], |
| device_info.max_work_group_size, |
| device_info.image_pitch_alignment); |
| } |
| |
| // get platform name string length |
| size_t sz = 0; |
| if (clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, 0, 0, &sz) != CL_SUCCESS) |
| { |
| XCAM_LOG_WARNING ("get cl platform name failed"); |
| return false; |
| } |
| |
| // get platform name string |
| if (sz >= XCAM_CL_MAX_STR_SIZE) { |
| sz = XCAM_CL_MAX_STR_SIZE - 1; |
| } |
| if (clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, sz, _platform_name, 0) != CL_SUCCESS) |
| { |
| XCAM_LOG_WARNING ("get cl platform name failed"); |
| return false; |
| } |
| |
| _platform_id = platform_id; |
| _device_id = device_id; |
| _device_info = device_info; |
| _platform_name[sz] = 0; |
| _inited = true; |
| return true; |
| } |
| |
| bool |
| CLDevice::query_device_info (cl_device_id device_id, CLDevieInfo &info) |
| { |
| #undef XCAM_CL_GET_DEVICE_INFO |
| #define XCAM_CL_GET_DEVICE_INFO(name, val) \ |
| do { \ |
| if (clGetDeviceInfo (device_id, name, sizeof (val), &(val), NULL) != CL_SUCCESS) { \ |
| XCAM_LOG_WARNING ("cl get device info(%s) failed", #name); \ |
| } } while (0) |
| |
| XCAM_CL_GET_DEVICE_INFO (CL_DEVICE_MAX_COMPUTE_UNITS, info.max_compute_unit); |
| XCAM_CL_GET_DEVICE_INFO (CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, info.max_work_item_dims); |
| XCAM_CL_GET_DEVICE_INFO (CL_DEVICE_MAX_WORK_ITEM_SIZES, info.max_work_item_sizes); |
| XCAM_CL_GET_DEVICE_INFO (CL_DEVICE_MAX_WORK_GROUP_SIZE, info.max_work_group_size); |
| XCAM_CL_GET_DEVICE_INFO (CL_DEVICE_MAX_WORK_GROUP_SIZE, info.max_work_group_size); |
| |
| cl_uint alignment = 0; |
| XCAM_CL_GET_DEVICE_INFO (CL_DEVICE_IMAGE_PITCH_ALIGNMENT, alignment); |
| if (alignment) |
| info.image_pitch_alignment = alignment; |
| else |
| info.image_pitch_alignment = 4; |
| return true; |
| } |
| |
| bool |
| CLDevice::create_default_context () |
| { |
| SmartPtr<CLContext> context; |
| |
| #if HAVE_LIBDRM |
| context = new CLIntelContext (_instance); |
| #else |
| context = new CLContext (_instance); |
| #endif |
| if (!context->is_valid()) |
| return false; |
| |
| // init first cmdqueue |
| if (context->is_valid () && !context->init_cmd_queue (context)) { |
| XCAM_LOG_ERROR ("CL context init cmd queue failed"); |
| } |
| _default_context = context; |
| return true; |
| } |
| |
| }; |