JNIEXPORT jint JNICALL Java_org_lwjgl_opencl_KHRGLSharing_nclGetGLContextInfoKHR(JNIEnv *env, jclass clazz, jobject properties, jint properties_position, jint param_name, jlong param_value_size, jobject param_value, jint param_value_position, jobject param_value_size_ret, jint param_value_size_ret_position, jlong function_pointer) { const cl_context_properties *properties_address = ((const cl_context_properties *)(((char *)(*env)->GetDirectBufferAddress(env, properties)) + properties_position)); cl_void *param_value_address = ((cl_void *)(((char *)safeGetBufferAddress(env, param_value)) + param_value_position)); size_t *param_value_size_ret_address = ((size_t *)(((char *)safeGetBufferAddress(env, param_value_size_ret)) + param_value_size_ret_position)); clGetGLContextInfoKHRPROC clGetGLContextInfoKHR = (clGetGLContextInfoKHRPROC)((intptr_t)function_pointer); cl_int __result = clGetGLContextInfoKHR(properties_address, param_name, param_value_size, param_value_address, param_value_size_ret_address); return __result; }
JNIEXPORT jint JNICALL Java_org_lwjgl_opencl_KHRGLSharing_nclGetGLContextInfoKHR(JNIEnv *env, jclass clazz, jlong properties, jint param_name, jlong param_value_size, jlong param_value, jlong param_value_size_ret, jlong function_pointer) { const cl_context_properties *properties_address = (const cl_context_properties *)(intptr_t)properties; cl_void *param_value_address = (cl_void *)(intptr_t)param_value; size_t *param_value_size_ret_address = (size_t *)(intptr_t)param_value_size_ret; clGetGLContextInfoKHRPROC clGetGLContextInfoKHR = (clGetGLContextInfoKHRPROC)((intptr_t)function_pointer); cl_int __result = clGetGLContextInfoKHR(properties_address, param_name, param_value_size, param_value_address, param_value_size_ret_address); return __result; }
CL::CL() { cl_int err; std::vector<cl::Platform> platforms; if(cl::Platform::get(&platforms) == CL_INVALID_VALUE) { fprintf(stderr, "[OpenCL] No platforms available\n"); util_abort(); } platform_ = platforms[0]; //Just select the first platform std::string name, version, extensions; platform_.getInfo(CL_PLATFORM_NAME, &name); platform_.getInfo(CL_PLATFORM_VERSION, &version); platform_.getInfo(CL_PLATFORM_EXTENSIONS, &extensions); fprintf(verbose, "[OpenCL] Platform: %s %s\n" " Extensions: %s\n", name.c_str(), version.c_str() ,extensions.c_str()); #if defined (__APPLE__) || defined(MACOSX) CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; #elif defined WIN32 HGLRC current_context = wglGetCurrentContext(); HDC current_dc = wglGetCurrentDC(); if(current_dc == NULL || current_context == NULL) { fprintf(stderr,"[OpenCL] No OpenGL context active\n"); util_abort(); } cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform_(), CL_WGL_HDC_KHR, (intptr_t) current_dc, CL_GL_CONTEXT_KHR, (intptr_t) current_context, 0 }; #else if(glXGetCurrentContext() == NULL) { fprintf(stderr, "[OpenCL] glXGetCurrentContex() return NULL. Make sure to create OpenGL context before create the CL-context\n"); util_abort(); } cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties)(platform_)(), 0 }; #endif static CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR)(const cl_context_properties *properties, cl_gl_context_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)=NULL; clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddress("clGetGLContextInfoKHR"); cl_device_id devices[32]; size_t deviceSize = 0; err = clGetGLContextInfoKHR(properties, CL_DEVICES_FOR_GL_CONTEXT_KHR, 32 * sizeof(cl_device_id), devices, &deviceSize); if(deviceSize == 0) { fprintf(stderr, "[OpenCL] Interop not possible\n"); util_abort(); } cl_bool image_support, available; size_t max_width, max_height; cl_uint num_cores, frequency; cl_device_type _type; std::string type; fprintf(verbose, "[OpenCL] Available devices: \n"); for(int i=0; i< (deviceSize / sizeof(cl_device_id)); ++i) { cl::Device device(devices[i]); device.getInfo(CL_DEVICE_VENDOR, &name); device.getInfo(CL_DEVICE_VERSION, &version); device.getInfo(CL_DEVICE_EXTENSIONS, &extensions); device.getInfo(CL_DEVICE_AVAILABLE, &available); device.getInfo(CL_DEVICE_IMAGE_SUPPORT, &image_support); device.getInfo(CL_DEVICE_IMAGE2D_MAX_WIDTH, &max_width); device.getInfo(CL_DEVICE_IMAGE2D_MAX_HEIGHT, &max_height); device.getInfo( CL_DEVICE_MAX_COMPUTE_UNITS , &num_cores); device.getInfo(CL_DEVICE_MAX_CLOCK_FREQUENCY, &frequency); device.getInfo(CL_DEVICE_TYPE, &_type); switch(_type) { case CL_DEVICE_TYPE_GPU: type = "GPU"; break; case CL_DEVICE_TYPE_CPU: type = "CPU"; break; case CL_DEVICE_TYPE_ACCELERATOR: type = "Accelerator"; break; } fprintf(verbose, "[OpenCL] Device (%p): %s %s (%s)\n" " Cores: %u, Frequency: %u MHz, Available: %s," " Image support: %s, max size: %lux%lu\n" " Extensions: %s\n --- \n", (device)(), name.c_str(), version.c_str(), type.c_str(), num_cores, frequency,available?"YES":"NO",image_support?"YES":"NO", max_width, max_height, extensions.c_str()); devices_.push_back(device); } fprintf(verbose, "\n-------------------\n"); cl_device_id device_id; context_ = cl::Context(devices_, properties, &CL::cl_error_callback, nullptr, &err); if(err != CL_SUCCESS) { fprintf(stderr, "[OpenCL] Failed to create context: %s\n", errorString(err)); util_abort(); } err = clGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(device_id), &device_id, NULL); if(err != CL_SUCCESS) { fprintf(stderr, "[OpenCL] Failed to get current device for context: %s\n", errorString(err)); util_abort(); } context_device_ = cl::Device(device_id); context_device_.getInfo(CL_DEVICE_VENDOR, &name); context_device_.getInfo(CL_DEVICE_VERSION, &version); fprintf(verbose, "[OpenCL] Context Device (%p): %s %s\n",(context_device_)(), name.c_str(), version.c_str()); queue_ = cl::CommandQueue(context_, context_device_, 0, &err); if(err != CL_SUCCESS) { fprintf(stderr, "[OpenCL] Failed to create a command queue: %s\n", errorString(err)); util_abort(); } }
CLContext::CLContext() { #if defined(__APPLE__) CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; context_ = clCreateContext(properties, 0, 0, clLogMessagesToStdoutAPPLE, 0, 0); if (!context_) crash("failed to create context"); uint device_count; cl_device_id device_ids[16]; size_t returned_size; int err = clGetContextInfo(context_, CL_CONTEXT_DEVICES, sizeof(device_ids), device_ids, &returned_size); if (err != CL_SUCCESS) crash("failed to get devices"); device_count = (int)returned_size / sizeof(cl_device_id); int i = 0; bool device_found = false; cl_device_type device_type; for (i = 0; i < device_count; i++) { clGetDeviceInfo(device_ids[i], CL_DEVICE_TYPE, sizeof(cl_device_type), &device_type, NULL); if (device_type == CL_DEVICE_TYPE_GPU) { device_id_ = device_ids[i]; device_found = true; break; } } if (!device_found) crash("no GPU device found"); #elif defined(WIN32) HGLRC hrc = wglGetCurrentContext(); HDC hdc = wglGetCurrentDC(); if (!hrc || !hdc) crash("failed to get HDC or HGLRC"); cl_platform_id platform_ids[16]; size_t platform_count; int err = clGetPlatformIDs(sizeof(platform_ids) / sizeof(platform_ids[0]), platform_ids, &platform_count); if (err != CL_SUCCESS || !platform_count) crash("failed to get platforms"); for (uint i = 0; i < platform_count; ++i) { char platform_name[100]; char platform_version[100]; char platform_vendor[100]; char platform_extensions[1000]; err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME, sizeof(platform_name), platform_name, NULL); if (err != CL_SUCCESS) crash("failed to get platform name"); err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_VERSION, sizeof(platform_version), platform_version, NULL); if (err != CL_SUCCESS) crash("failed to get platform version"); err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_VENDOR, sizeof(platform_vendor), platform_vendor, NULL); if (err != CL_SUCCESS) crash("failed to get platform vendor"); err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_EXTENSIONS, sizeof(platform_extensions), platform_extensions, NULL); if (err != CL_SUCCESS) crash("failed to get platform extensions"); cout << "platform name: " << platform_name << endl; cout << "platform version: " << platform_version << endl; cout << "platform vendor: " << platform_vendor << endl; cout << "platform extensions: " << platform_extensions << endl; cout << endl; } cl_platform_id platform_id = platform_ids[0]; typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)( const cl_context_properties *properties, cl_gl_context_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret); clGetGLContextInfoKHR_fn clGetGLContextInfoKHR; clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddress("clGetGLContextInfoKHR"); if (!clGetGLContextInfoKHR) crash("failed to query proc address for clGetGLContextInfoKHR"); #ifndef NO_OPENGL_SHARING cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platform_id, CL_GL_CONTEXT_KHR, (cl_context_properties) hrc, CL_WGL_HDC_KHR, (cl_context_properties) hdc, 0 }; size_t device_count; err = clGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(device_id_), &device_id_, &device_count); if (err != CL_SUCCESS || !device_count) crash("failed to get CL device from GL context"); char device_name[100]; char device_version[100]; cl_device_type device_type; cl_bool device_image_support; err = clGetDeviceInfo(device_id_, CL_DEVICE_NAME, sizeof(device_name), device_name, NULL); if (err != CL_SUCCESS) crash("failed to get device name"); err = clGetDeviceInfo(device_id_, CL_DEVICE_VERSION, sizeof(device_version), device_version, NULL); if (err != CL_SUCCESS) crash("failed to get device version"); err = clGetDeviceInfo(device_id_, CL_DEVICE_TYPE, sizeof(device_type), &device_type, NULL); if (err != CL_SUCCESS) crash("failed to get device type"); err = clGetDeviceInfo(device_id_, CL_DEVICE_IMAGE_SUPPORT, sizeof(device_image_support), &device_image_support, NULL); if (err != CL_SUCCESS) crash("failed to get device image support"); cout << "device name: " << device_name << endl; cout << "device version: " << device_version << endl; cout << "device type: " << ((device_type & CL_DEVICE_TYPE_GPU) ? "GPU" : "not GPU") << endl; cout << "device image support: " << (device_image_support ? "yes" : "no") << endl; cout << endl; context_ = clCreateContext(properties, 1, &device_id_, 0, 0, &err); #else cl_int error = 0; cl_platform_id platform; // Platform error = clGetPlatformIDs(1, &platform, NULL); if (error != CL_SUCCESS) { cout << "Error getting platform id: " << error << endl; exit(error); } // Device error = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device_id_, NULL); if (err != CL_SUCCESS) { cout << "Error getting device ids: " << error << endl; exit(error); } // Context context_ = clCreateContext(0, 1, &device_id_, NULL, NULL, &error); if (error != CL_SUCCESS) { cout << "Error creating context: " << error << endl; exit(error); } #endif #endif cl_command_queue_properties queue_properties = 0; queue_properties |= CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE; #ifdef PROFILING_ENABLED queue_properties |= CL_QUEUE_PROFILING_ENABLE; #endif queue_ = clCreateCommandQueue(context_, device_id_, queue_properties, NULL); if (!queue_) crash("failed to create command queue"); }
bool selectGLDeviceAndPlatform(cl_device_id *device, cl_platform_id *platform) { assert(device != nullptr); assert(platform != nullptr); /* first try to get the necessary extension */ clGetGLContextInfoKHR_fn clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddress("clGetGLContextInfoKHR"); if (clGetGLContextInfoKHR == nullptr) { ERRORM("clGetGLContextInfoKHR extension function not supproted."); return false; } #if defined(FLUIDSIM_OS_MAC) cl_context_properties props[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties) CGLGetShareGroup(CGLGetCurrentContext()), 0 }; cl_int err = clGetGLContextInfoKHR(props, // the OpenGL context CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, // get the id of the device currently executing OpenGL sizeof(*device), device, nullptr); if (err != CL_SUCCESS) { ERRORM("Failed to retrieve the OpenCL id of the device executing OpenGL: " << errorToStr(err)); return false; } /* get the platform associated with the device */ err = clGetDeviceInfo(*device, CL_DEVICE_PLATFORM, sizeof(*platform), platform, nullptr); if (err != CL_SUCCESS) { ERRORM("Failed to retirieve platform id for the device executing OpenGL: " << errorToStr(err)); return false; } #else cl_context_properties props[] = { #if defined(FLUIDSIM_OS_UNIX) CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties) nullptr, #elif defined(FLUIDSIM_OS_WIN) CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties) nullptr, #else # error "Unsupported OS platform" #endif 0 }; std::vector<boost::compute::platform> platform_list = boost::compute::system::platforms(); for (const boost::compute::platform & p : platform_list) { WARNM("platform: " << p.name()); props[5] = (cl_context_properties) p.id(); cl_int err = clGetGLContextInfoKHR(props, // the OpenGL context CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, // get the id of the device currently executing OpenGL sizeof(*device), device, nullptr); if ((err == CL_SUCCESS) && (boost::compute::device(*device).type() == CL_DEVICE_TYPE_GPU)) { *platform = (cl_platform_id) props[5]; return true; } else { WARNM("clGetGLContextInfoKHR: " << errorToStr(err)); } } #endif return false; }