2 Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
3 Copyright (C) 2006 - 2011 Sony Computer Entertainment Inc.
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
16 //original author: Roman Ponomarev
17 //cleanup by Erwin Coumans
21 #include "btOpenCLUtils.h"
25 #define BT_MAX_CL_DEVICES 16 //who needs 16 devices?
31 #define btAssert assert
34 //Set the preferred platform vendor using the OpenCL SDK
35 static char* spPlatformVendor =
36 #if defined(CL_PLATFORM_MINI_CL)
38 #elif defined(CL_PLATFORM_AMD)
39 "Advanced Micro Devices, Inc.";
40 #elif defined(CL_PLATFORM_NVIDIA)
42 #elif defined(CL_PLATFORM_INTEL)
43 "Intel(R) Corporation";
48 #ifndef CL_PLATFORM_MINI_CL
54 int btOpenCLUtils::getNumPlatforms(cl_int* pErrNum)
56 cl_uint numPlatforms=0;
57 cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
59 if(ciErrNum != CL_SUCCESS)
67 const char* btOpenCLUtils::getSdkVendorName()
69 return spPlatformVendor;
72 cl_platform_id btOpenCLUtils::getPlatform(int platformIndex, cl_int* pErrNum)
74 cl_platform_id platform = 0;
77 cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
79 if (platformIndex>=0 && platformIndex<numPlatforms)
81 cl_platform_id* platforms = new cl_platform_id[numPlatforms];
82 ciErrNum = clGetPlatformIDs(numPlatforms, platforms, NULL);
83 if(ciErrNum != CL_SUCCESS)
90 platform = platforms[platformIndex];
98 void btOpenCLUtils::getPlatformInfo(cl_platform_id platform, btOpenCLPlatformInfo& platformInfo)
102 ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_VENDOR,BT_MAX_STRING_LENGTH,platformInfo.m_platformVendor,NULL);
103 oclCHECKERROR(ciErrNum,CL_SUCCESS);
104 ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_NAME,BT_MAX_STRING_LENGTH,platformInfo.m_platformName,NULL);
105 oclCHECKERROR(ciErrNum,CL_SUCCESS);
106 ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_VERSION,BT_MAX_STRING_LENGTH,platformInfo.m_platformVersion,NULL);
107 oclCHECKERROR(ciErrNum,CL_SUCCESS);
110 cl_context btOpenCLUtils::createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC, int preferredDeviceIndex, int preferredPlatformIndex)
112 cl_context retContext = 0;
116 * If we could find our platform, use it. Otherwise pass a NULL and get whatever the
117 * implementation thinks we should be using.
119 cl_context_properties cps[7] = {0,0,0,0,0,0,0};
120 cps[0] = CL_CONTEXT_PLATFORM;
121 cps[1] = (cl_context_properties)platform;
122 if (pGLContext && pGLDC)
124 cps[2] = CL_GL_CONTEXT_KHR;
125 cps[3] = (cl_context_properties)pGLContext;
126 cps[4] = CL_WGL_HDC_KHR;
127 cps[5] = (cl_context_properties)pGLDC;
130 cl_uint num_entries = BT_MAX_CL_DEVICES;
131 cl_device_id devices[BT_MAX_CL_DEVICES];
133 cl_uint num_devices=-1;
135 ciErrNum = clGetDeviceIDs(
142 cl_context_properties* cprops = (NULL == platform) ? NULL : cps;
146 //search for the GPU that relates to the OpenCL context
147 for (int i=0;i<num_devices;i++)
149 retContext = clCreateContext(cprops,1,&devices[i],NULL,NULL,&ciErrNum);
150 if (ciErrNum==CL_SUCCESS)
156 if (preferredDeviceIndex>=0 && preferredDeviceIndex<num_devices)
158 //create a context of the preferred device index
159 retContext = clCreateContext(cprops,1,&devices[preferredDeviceIndex],NULL,NULL,&ciErrNum);
162 //create a context of all devices
163 retContext = clCreateContext(cprops,num_devices,devices,NULL,NULL,&ciErrNum);
174 cl_context btOpenCLUtils::createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC , int preferredDeviceIndex, int preferredPlatformIndex)
176 cl_uint numPlatforms;
177 cl_context retContext = 0;
179 cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
180 if(ciErrNum != CL_SUCCESS)
182 if(pErrNum != NULL) *pErrNum = ciErrNum;
187 cl_platform_id* platforms = new cl_platform_id[numPlatforms];
188 ciErrNum = clGetPlatformIDs(numPlatforms, platforms, NULL);
189 if(ciErrNum != CL_SUCCESS)
191 if(pErrNum != NULL) *pErrNum = ciErrNum;
197 for ( i = 0; i < numPlatforms; ++i)
200 ciErrNum = clGetPlatformInfo( platforms[i],
205 if(ciErrNum != CL_SUCCESS)
207 if(pErrNum != NULL) *pErrNum = ciErrNum;
211 if (preferredPlatformIndex>=0 && i==preferredPlatformIndex)
213 cl_platform_id tmpPlatform = platforms[0];
214 platforms[0] = platforms[i];
215 platforms[i] = tmpPlatform;
219 if(!strcmp(pbuf, spPlatformVendor))
221 cl_platform_id tmpPlatform = platforms[0];
222 platforms[0] = platforms[i];
223 platforms[i] = tmpPlatform;
229 for (i = 0; i < numPlatforms; ++i)
231 cl_platform_id platform = platforms[i];
234 retContext = btOpenCLUtils::createContextFromPlatform(platform,deviceType,pErrNum,pGLContext,pGLDC,preferredDeviceIndex);
238 // printf("OpenCL platform details:\n");
239 btOpenCLPlatformInfo platformInfo;
241 btOpenCLUtils::getPlatformInfo(platform, platformInfo);
243 printf(" CL_PLATFORM_VENDOR: \t\t\t%s\n",platformInfo.m_platformVendor);
244 printf(" CL_PLATFORM_NAME: \t\t\t%s\n",platformInfo.m_platformName);
245 printf(" CL_PLATFORM_VERSION: \t\t\t%s\n",platformInfo.m_platformVersion);
257 //////////////////////////////////////////////////////////////////////////////
258 //! Gets the id of the nth device from the context
260 //! @return the id or -1 when out of range
261 //! @param cxMainContext OpenCL context
262 //! @param device_idx index of the device of interest
263 //////////////////////////////////////////////////////////////////////////////
264 cl_device_id btOpenCLUtils::getDevice(cl_context cxMainContext, int deviceIndex)
266 size_t szParmDataBytes;
267 cl_device_id* cdDevices;
269 // get the list of devices associated with context
270 clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes);
272 if( szParmDataBytes / sizeof(cl_device_id) < deviceIndex ) {
273 return (cl_device_id)-1;
276 cdDevices = (cl_device_id*) malloc(szParmDataBytes);
278 clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL);
280 cl_device_id device = cdDevices[deviceIndex];
286 int btOpenCLUtils::getNumDevices(cl_context cxMainContext)
288 size_t szParamDataBytes;
289 clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParamDataBytes);
290 int device_count = (int) szParamDataBytes/ sizeof(cl_device_id);
294 void btOpenCLUtils::printDeviceInfo(cl_device_id device)
296 btOpenCLDeviceInfo info;
297 getDeviceInfo(device,info);
299 printf(" CL_DEVICE_NAME: \t\t\t%s\n", info.m_deviceName);
300 printf(" CL_DEVICE_VENDOR: \t\t\t%s\n", info.m_deviceVendor);
301 printf(" CL_DRIVER_VERSION: \t\t\t%s\n", info.m_driverVersion);
303 if( info.m_deviceType & CL_DEVICE_TYPE_CPU )
304 printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_CPU");
305 if( info.m_deviceType & CL_DEVICE_TYPE_GPU )
306 printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_GPU");
307 if( info.m_deviceType & CL_DEVICE_TYPE_ACCELERATOR )
308 printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_ACCELERATOR");
309 if( info.m_deviceType & CL_DEVICE_TYPE_DEFAULT )
310 printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_DEFAULT");
312 printf(" CL_DEVICE_MAX_COMPUTE_UNITS:\t\t%u\n", info.m_computeUnits);
313 printf(" CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:\t%u\n", info.m_workitemDims);
314 printf(" CL_DEVICE_MAX_WORK_ITEM_SIZES:\t%u / %u / %u \n", info.m_workItemSize[0], info.m_workItemSize[1], info.m_workItemSize[2]);
315 printf(" CL_DEVICE_MAX_WORK_GROUP_SIZE:\t%u\n", info.m_workgroupSize);
316 printf(" CL_DEVICE_MAX_CLOCK_FREQUENCY:\t%u MHz\n", info.m_clockFrequency);
317 printf(" CL_DEVICE_ADDRESS_BITS:\t\t%u\n", info.m_addressBits);
318 printf(" CL_DEVICE_MAX_MEM_ALLOC_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_maxMemAllocSize/ (1024 * 1024)));
319 printf(" CL_DEVICE_GLOBAL_MEM_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_globalMemSize/ (1024 * 1024)));
320 printf(" CL_DEVICE_ERROR_CORRECTION_SUPPORT:\t%s\n", info.m_errorCorrectionSupport== CL_TRUE ? "yes" : "no");
321 printf(" CL_DEVICE_LOCAL_MEM_TYPE:\t\t%s\n", info.m_localMemType == 1 ? "local" : "global");
322 printf(" CL_DEVICE_LOCAL_MEM_SIZE:\t\t%u KByte\n", (unsigned int)(info.m_localMemSize / 1024));
323 printf(" CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:\t%u KByte\n", (unsigned int)(info.m_constantBufferSize / 1024));
324 if( info.m_queueProperties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE )
325 printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE");
326 if( info.m_queueProperties & CL_QUEUE_PROFILING_ENABLE )
327 printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_PROFILING_ENABLE");
329 printf(" CL_DEVICE_IMAGE_SUPPORT:\t\t%u\n", info.m_imageSupport);
331 printf(" CL_DEVICE_MAX_READ_IMAGE_ARGS:\t%u\n", info.m_maxReadImageArgs);
332 printf(" CL_DEVICE_MAX_WRITE_IMAGE_ARGS:\t%u\n", info.m_maxWriteImageArgs);
333 printf("\n CL_DEVICE_IMAGE <dim>");
334 printf("\t\t\t2D_MAX_WIDTH\t %u\n", info.m_image2dMaxWidth);
335 printf("\t\t\t\t\t2D_MAX_HEIGHT\t %u\n", info.m_image2dMaxHeight);
336 printf("\t\t\t\t\t3D_MAX_WIDTH\t %u\n", info.m_image3dMaxWidth);
337 printf("\t\t\t\t\t3D_MAX_HEIGHT\t %u\n", info.m_image3dMaxHeight);
338 printf("\t\t\t\t\t3D_MAX_DEPTH\t %u\n", info.m_image3dMaxDepth);
339 if (info.m_deviceExtensions != 0)
340 printf("\n CL_DEVICE_EXTENSIONS:%s\n",info.m_deviceExtensions);
342 printf(" CL_DEVICE_EXTENSIONS: None\n");
343 printf(" CL_DEVICE_PREFERRED_VECTOR_WIDTH_<t>\t");
344 printf("CHAR %u, SHORT %u, INT %u,LONG %u, FLOAT %u, DOUBLE %u\n\n\n",
345 info.m_vecWidthChar, info.m_vecWidthShort, info.m_vecWidthInt, info.m_vecWidthLong,info.m_vecWidthFloat, info.m_vecWidthDouble);
350 void btOpenCLUtils::getDeviceInfo(cl_device_id device, btOpenCLDeviceInfo& info)
354 clGetDeviceInfo(device, CL_DEVICE_NAME, BT_MAX_STRING_LENGTH, &info.m_deviceName, NULL);
357 clGetDeviceInfo(device, CL_DEVICE_VENDOR, BT_MAX_STRING_LENGTH, &info.m_deviceVendor, NULL);
360 clGetDeviceInfo(device, CL_DRIVER_VERSION, BT_MAX_STRING_LENGTH, &info.m_driverVersion, NULL);
363 clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(cl_device_type), &info.m_deviceType, NULL);
365 // CL_DEVICE_MAX_COMPUTE_UNITS
366 clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(info.m_computeUnits), &info.m_computeUnits, NULL);
368 // CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
369 clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(info.m_workitemDims), &info.m_workitemDims, NULL);
371 // CL_DEVICE_MAX_WORK_ITEM_SIZES
372 clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(info.m_workItemSize), &info.m_workItemSize, NULL);
374 // CL_DEVICE_MAX_WORK_GROUP_SIZE
375 clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(info.m_workgroupSize), &info.m_workgroupSize, NULL);
377 // CL_DEVICE_MAX_CLOCK_FREQUENCY
378 clGetDeviceInfo(device, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(info.m_clockFrequency), &info.m_clockFrequency, NULL);
380 // CL_DEVICE_ADDRESS_BITS
381 clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(info.m_addressBits), &info.m_addressBits, NULL);
383 // CL_DEVICE_MAX_MEM_ALLOC_SIZE
384 clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(info.m_maxMemAllocSize), &info.m_maxMemAllocSize, NULL);
386 // CL_DEVICE_GLOBAL_MEM_SIZE
387 clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(info.m_globalMemSize), &info.m_globalMemSize, NULL);
389 // CL_DEVICE_ERROR_CORRECTION_SUPPORT
390 clGetDeviceInfo(device, CL_DEVICE_ERROR_CORRECTION_SUPPORT, sizeof(info.m_errorCorrectionSupport), &info.m_errorCorrectionSupport, NULL);
392 // CL_DEVICE_LOCAL_MEM_TYPE
393 clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_TYPE, sizeof(info.m_localMemType), &info.m_localMemType, NULL);
395 // CL_DEVICE_LOCAL_MEM_SIZE
396 clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(info.m_localMemSize), &info.m_localMemSize, NULL);
398 // CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE
399 clGetDeviceInfo(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof(info.m_constantBufferSize), &info.m_constantBufferSize, NULL);
401 // CL_DEVICE_QUEUE_PROPERTIES
402 clGetDeviceInfo(device, CL_DEVICE_QUEUE_PROPERTIES, sizeof(info.m_queueProperties), &info.m_queueProperties, NULL);
404 // CL_DEVICE_IMAGE_SUPPORT
405 clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT, sizeof(info.m_imageSupport), &info.m_imageSupport, NULL);
407 // CL_DEVICE_MAX_READ_IMAGE_ARGS
408 clGetDeviceInfo(device, CL_DEVICE_MAX_READ_IMAGE_ARGS, sizeof(info.m_maxReadImageArgs), &info.m_maxReadImageArgs, NULL);
410 // CL_DEVICE_MAX_WRITE_IMAGE_ARGS
411 clGetDeviceInfo(device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, sizeof(info.m_maxWriteImageArgs), &info.m_maxWriteImageArgs, NULL);
413 // CL_DEVICE_IMAGE2D_MAX_WIDTH, CL_DEVICE_IMAGE2D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_WIDTH, CL_DEVICE_IMAGE3D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_DEPTH
414 clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &info.m_image2dMaxWidth, NULL);
415 clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), &info.m_image2dMaxHeight, NULL);
416 clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof(size_t), &info.m_image3dMaxWidth, NULL);
417 clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof(size_t), &info.m_image3dMaxHeight, NULL);
418 clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &info.m_image3dMaxDepth, NULL);
420 // CL_DEVICE_EXTENSIONS: get device extensions, and if any then parse & log the string onto separate lines
421 clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, BT_MAX_STRING_LENGTH, &info.m_deviceExtensions, NULL);
423 // CL_DEVICE_PREFERRED_VECTOR_WIDTH_<type>
424 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &info.m_vecWidthChar, NULL);
425 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, sizeof(cl_uint), &info.m_vecWidthShort, NULL);
426 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), &info.m_vecWidthInt, NULL);
427 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, sizeof(cl_uint), &info.m_vecWidthLong, NULL);
428 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof(cl_uint), &info.m_vecWidthFloat, NULL);
429 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), &info.m_vecWidthDouble, NULL);
432 static const char* strip2(const char* name, const char* pattern)
434 size_t const patlen = strlen(pattern);
438 // find how many times the pattern occurs in the original string
439 for (oriptr = name; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
446 cl_program btOpenCLUtils::compileCLProgramFromString(cl_context clContext, cl_device_id device, const char* kernelSource, cl_int* pErrNum, const char* additionalMacros , const char* clFileNameForCaching)
449 cl_program m_cpProgram=0;
452 char binaryFileName[522];
454 if (clFileNameForCaching)
457 char deviceName[256];
458 char driverVersion[256];
459 clGetDeviceInfo(device, CL_DEVICE_NAME, 256, &deviceName, NULL);
460 clGetDeviceInfo(device, CL_DRIVER_VERSION, 256, &driverVersion, NULL);
463 const char* strippedName = strip2(clFileNameForCaching,"\\");
464 strippedName = strip2(strippedName,"/");
466 sprintf_s(binaryFileName,"cache/%s.%s.%s.bin",strippedName, deviceName,driverVersion );
467 //printf("searching for %s\n", binaryFileName);
469 bool fileUpToDate = false;
470 bool binaryFileValid=false;
472 FILETIME modtimeBinary;
475 CreateDirectory("cache",0);
478 HANDLE binaryFileHandle = CreateFile(binaryFileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
479 if (binaryFileHandle ==INVALID_HANDLE_VALUE)
482 errorCode = GetLastError();
485 case ERROR_FILE_NOT_FOUND:
487 printf("\nCached file not found %s\n", binaryFileName);
490 case ERROR_PATH_NOT_FOUND:
492 printf("\nCached file path not found %s\n", binaryFileName);
497 printf("\nFailed reading cached file with errorCode = %d\n", errorCode);
502 if (GetFileTime(binaryFileHandle, NULL, NULL, &modtimeBinary)==0)
505 errorCode = GetLastError();
506 printf("\nGetFileTime errorCode = %d\n", errorCode);
509 binaryFileValid = true;
511 CloseHandle(binaryFileHandle);
516 HANDLE srcFileHandle = CreateFile(clFileNameForCaching,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
517 if (srcFileHandle!=INVALID_HANDLE_VALUE)
520 if (GetFileTime(srcFileHandle, NULL, NULL, &modtimeSrc)==0)
523 errorCode = GetLastError();
524 printf("\nGetFileTime errorCode = %d\n", errorCode);
526 if ( ( modtimeSrc.dwHighDateTime < modtimeBinary.dwHighDateTime)
527 ||(( modtimeSrc.dwHighDateTime == modtimeBinary.dwHighDateTime)&&(modtimeSrc.dwLowDateTime <= modtimeBinary.dwLowDateTime)))
532 printf("\nCached binary file out-of-date (%s)\n",binaryFileName);
534 CloseHandle(srcFileHandle);
540 errorCode = GetLastError();
543 case ERROR_FILE_NOT_FOUND:
545 printf("\nSrc file not found %s\n", clFileNameForCaching);
548 case ERROR_PATH_NOT_FOUND:
550 printf("\nSrc path not found %s\n", clFileNameForCaching);
555 printf("\nnSrc file reading errorCode = %d\n", errorCode);
559 //we should make sure the src file exists so we can verify the timestamp with binary
562 //if we cannot find the source, assume it is OK in release builds
573 FILE* file = fopen(binaryFileName, "rb");
576 fseek( file, 0L, SEEK_END );
577 size_t binarySize = ftell( file );
579 char* binary = new char[binarySize];
580 fread( binary, sizeof(char), binarySize, file );
583 m_cpProgram = clCreateProgramWithBinary( clContext, 1,&device, &binarySize, (const unsigned char**)&binary, 0, &status );
584 btAssert( status == CL_SUCCESS );
585 status = clBuildProgram( m_cpProgram, 1, &device, additionalMacros, 0, 0 );
586 btAssert( status == CL_SUCCESS );
588 if( status != CL_SUCCESS )
592 clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
593 build_log = new char[ret_val_size+1];
594 clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
595 build_log[ret_val_size] = '\0';
596 printf("%s\n", build_log);
612 size_t program_length = strlen(kernelSource);
614 m_cpProgram = clCreateProgramWithSource(clContext, 1, (const char**)&kernelSource, &program_length, &localErrNum);
615 if (localErrNum!= CL_SUCCESS)
618 *pErrNum = localErrNum;
622 // Build the program with 'mad' Optimization option
626 char* flags = "-cl-mad-enable -DMAC -DGUID_ARG";
628 //const char* flags = "-DGUID_ARG= -fno-alias";
629 const char* flags = "-DGUID_ARG= ";
632 char* compileFlags = new char[strlen(additionalMacros) + strlen(flags) + 5];
633 sprintf(compileFlags, "%s %s", flags, additionalMacros);
634 localErrNum = clBuildProgram(m_cpProgram, 1, &device, compileFlags, NULL, NULL);
635 if (localErrNum!= CL_SUCCESS)
639 clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
640 build_log = new char[ret_val_size+1];
641 clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
643 // to be carefully, terminate with \0
644 // there's no information in the reference whether the string is 0 terminated or not
645 build_log[ret_val_size] = '\0';
648 printf("Error in clBuildProgram, Line %u in file %s, Log: \n%s\n !!!\n\n", __LINE__, __FILE__, build_log);
651 *pErrNum = localErrNum;
655 if( clFileNameForCaching )
658 cl_uint numAssociatedDevices;
659 status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_NUM_DEVICES, sizeof(cl_uint), &numAssociatedDevices, 0 );
660 btAssert( status == CL_SUCCESS );
661 if (numAssociatedDevices==1)
665 status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binarySize, 0 );
666 btAssert( status == CL_SUCCESS );
668 char* binary = new char[binarySize];
670 status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARIES, sizeof(char*), &binary, 0 );
671 btAssert( status == CL_SUCCESS );
674 FILE* file = fopen(binaryFileName, "wb");
677 fwrite( binary, sizeof(char), binarySize, file );
681 printf("cannot write file %s\n", binaryFileName);
688 delete [] compileFlags;
695 cl_kernel btOpenCLUtils::compileCLKernelFromString(cl_context clContext, cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum, cl_program prog, const char* additionalMacros )
697 printf("compiling kernel %s ",kernelName);
700 size_t program_length = strlen(kernelSource);
703 cl_program m_cpProgram = prog;
706 m_cpProgram = compileCLProgramFromString(clContext,device,kernelSource,pErrNum, additionalMacros);
711 kernel = clCreateKernel(m_cpProgram, kernelName, &localErrNum);
712 if (localErrNum != CL_SUCCESS)
714 printf("Error in clCreateKernel, Line %u in file %s, cannot find kernel function %s !!!\n\n", __LINE__, __FILE__, kernelName);
716 *pErrNum = localErrNum;
720 if (!prog && m_cpProgram)
722 clReleaseProgram(m_cpProgram);
728 *pErrNum = CL_SUCCESS;