2 Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
\r
3 Copyright (C) 2006 - 2011 Sony Computer Entertainment Inc.
\r
5 This software is provided 'as-is', without any express or implied warranty.
\r
6 In no event will the authors be held liable for any damages arising from the use of this software.
\r
7 Permission is granted to anyone to use this software for any purpose,
\r
8 including commercial applications, and to alter it and redistribute it freely,
\r
9 subject to the following restrictions:
\r
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.
\r
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
\r
13 3. This notice may not be removed or altered from any source distribution.
\r
16 //original author: Roman Ponomarev
\r
17 //cleanup by Erwin Coumans
\r
21 #include "btOpenCLUtils.h"
\r
25 #define BT_MAX_CL_DEVICES 16 //who needs 16 devices?
\r
26 //#define BT_USE_CACHE_DIR
\r
28 #include <Windows.h>
\r
32 #define btAssert assert
\r
34 //Set the preferred platform vendor using the OpenCL SDK
\r
35 static const char* spPlatformVendor =
\r
36 #if defined(CL_PLATFORM_MINI_CL)
\r
38 #elif defined(CL_PLATFORM_AMD)
\r
39 "Advanced Micro Devices, Inc.";
\r
40 #elif defined(CL_PLATFORM_NVIDIA)
\r
41 "NVIDIA Corporation";
\r
42 #elif defined(CL_PLATFORM_INTEL)
\r
43 "Intel(R) Corporation";
\r
48 #ifndef CL_PLATFORM_MINI_CL
\r
50 #include "CL/cl_gl.h"
\r
54 int btOpenCLUtils::getNumPlatforms(cl_int* pErrNum)
\r
56 cl_uint numPlatforms=0;
\r
57 cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
\r
59 if(ciErrNum != CL_SUCCESS)
\r
61 if(pErrNum != NULL)
\r
62 *pErrNum = ciErrNum;
\r
64 return numPlatforms;
\r
67 const char* btOpenCLUtils::getSdkVendorName()
\r
69 return spPlatformVendor;
\r
72 cl_platform_id btOpenCLUtils::getPlatform(int platformIndex, cl_int* pErrNum)
\r
74 cl_platform_id platform = 0;
\r
76 cl_uint numPlatforms;
\r
77 cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
\r
79 if (platformIndex>=0 && platformIndex<numPlatforms)
\r
81 cl_platform_id* platforms = new cl_platform_id[numPlatforms];
\r
82 ciErrNum = clGetPlatformIDs(numPlatforms, platforms, NULL);
\r
83 if(ciErrNum != CL_SUCCESS)
\r
85 if(pErrNum != NULL)
\r
86 *pErrNum = ciErrNum;
\r
90 platform = platforms[platformIndex];
\r
98 void btOpenCLUtils::getPlatformInfo(cl_platform_id platform, btOpenCLPlatformInfo& platformInfo)
\r
102 ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_VENDOR,BT_MAX_STRING_LENGTH,platformInfo.m_platformVendor,NULL);
\r
103 oclCHECKERROR(ciErrNum,CL_SUCCESS);
\r
104 ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_NAME,BT_MAX_STRING_LENGTH,platformInfo.m_platformName,NULL);
\r
105 oclCHECKERROR(ciErrNum,CL_SUCCESS);
\r
106 ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_VERSION,BT_MAX_STRING_LENGTH,platformInfo.m_platformVersion,NULL);
\r
107 oclCHECKERROR(ciErrNum,CL_SUCCESS);
\r
110 cl_context btOpenCLUtils::createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC, int preferredDeviceIndex, int preferredPlatformIndex)
\r
112 cl_context retContext = 0;
\r
116 * If we could find our platform, use it. Otherwise pass a NULL and get whatever the
\r
117 * implementation thinks we should be using.
\r
119 cl_context_properties cps[7] = {0,0,0,0,0,0,0};
\r
120 cps[0] = CL_CONTEXT_PLATFORM;
\r
121 cps[1] = (cl_context_properties)platform;
\r
122 if (pGLContext && pGLDC)
\r
124 #if defined(CL_PLATFORM_AMD) || defined(CL_PLATFORM_NVIDIA)
\r
125 cps[2] = CL_GL_CONTEXT_KHR;
\r
126 cps[3] = (cl_context_properties)pGLContext;
\r
127 cps[4] = CL_WGL_HDC_KHR;
\r
128 cps[5] = (cl_context_properties)pGLDC;
\r
132 cl_uint num_entries = BT_MAX_CL_DEVICES;
\r
133 cl_device_id devices[BT_MAX_CL_DEVICES];
\r
135 cl_uint num_devices=-1;
\r
137 ciErrNum = clGetDeviceIDs(
\r
144 cl_context_properties* cprops = (NULL == platform) ? NULL : cps;
\r
148 //search for the GPU that relates to the OpenCL context
\r
149 for (int i=0;i<num_devices;i++)
\r
151 retContext = clCreateContext(cprops,1,&devices[i],NULL,NULL,&ciErrNum);
\r
152 if (ciErrNum==CL_SUCCESS)
\r
158 if (preferredDeviceIndex>=0 && preferredDeviceIndex<num_devices)
\r
160 //create a context of the preferred device index
\r
161 retContext = clCreateContext(cprops,1,&devices[preferredDeviceIndex],NULL,NULL,&ciErrNum);
\r
164 //create a context of all devices
\r
165 retContext = clCreateContext(cprops,num_devices,devices,NULL,NULL,&ciErrNum);
\r
168 if(pErrNum != NULL)
\r
170 *pErrNum = ciErrNum;
\r
176 cl_context btOpenCLUtils::createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC , int preferredDeviceIndex, int preferredPlatformIndex)
\r
178 cl_uint numPlatforms;
\r
179 cl_context retContext = 0;
\r
181 cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
\r
182 if(ciErrNum != CL_SUCCESS)
\r
184 if(pErrNum != NULL) *pErrNum = ciErrNum;
\r
187 if(numPlatforms > 0)
\r
189 cl_platform_id* platforms = new cl_platform_id[numPlatforms];
\r
190 ciErrNum = clGetPlatformIDs(numPlatforms, platforms, NULL);
\r
191 if(ciErrNum != CL_SUCCESS)
\r
193 if(pErrNum != NULL) *pErrNum = ciErrNum;
\r
199 for ( i = 0; i < numPlatforms; ++i)
\r
202 ciErrNum = clGetPlatformInfo( platforms[i],
\r
203 CL_PLATFORM_VENDOR,
\r
207 if(ciErrNum != CL_SUCCESS)
\r
209 if(pErrNum != NULL) *pErrNum = ciErrNum;
\r
213 if (preferredPlatformIndex>=0 && i==preferredPlatformIndex)
\r
215 cl_platform_id tmpPlatform = platforms[0];
\r
216 platforms[0] = platforms[i];
\r
217 platforms[i] = tmpPlatform;
\r
221 if(!strcmp(pbuf, spPlatformVendor))
\r
223 cl_platform_id tmpPlatform = platforms[0];
\r
224 platforms[0] = platforms[i];
\r
225 platforms[i] = tmpPlatform;
\r
231 for (i = 0; i < numPlatforms; ++i)
\r
233 cl_platform_id platform = platforms[i];
\r
236 retContext = btOpenCLUtils::createContextFromPlatform(platform,deviceType,pErrNum,pGLContext,pGLDC,preferredDeviceIndex);
\r
240 // printf("OpenCL platform details:\n");
\r
241 btOpenCLPlatformInfo platformInfo;
\r
243 btOpenCLUtils::getPlatformInfo(platform, platformInfo);
\r
245 printf(" CL_PLATFORM_VENDOR: \t\t\t%s\n",platformInfo.m_platformVendor);
\r
246 printf(" CL_PLATFORM_NAME: \t\t\t%s\n",platformInfo.m_platformName);
\r
247 printf(" CL_PLATFORM_VERSION: \t\t\t%s\n",platformInfo.m_platformVersion);
\r
253 delete[] platforms;
\r
259 //////////////////////////////////////////////////////////////////////////////
\r
260 //! Gets the id of the nth device from the context
\r
262 //! @return the id or -1 when out of range
\r
263 //! @param cxMainContext OpenCL context
\r
264 //! @param device_idx index of the device of interest
\r
265 //////////////////////////////////////////////////////////////////////////////
\r
266 cl_device_id btOpenCLUtils::getDevice(cl_context cxMainContext, int deviceIndex)
\r
268 size_t szParmDataBytes;
\r
269 cl_device_id* cdDevices;
\r
271 // get the list of devices associated with context
\r
272 clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes);
\r
274 if( szParmDataBytes / sizeof(cl_device_id) < deviceIndex ) {
\r
275 return (cl_device_id)-1;
\r
278 cdDevices = (cl_device_id*) malloc(szParmDataBytes);
\r
280 clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL);
\r
282 cl_device_id device = cdDevices[deviceIndex];
\r
288 int btOpenCLUtils::getNumDevices(cl_context cxMainContext)
\r
290 size_t szParamDataBytes;
\r
291 clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParamDataBytes);
\r
292 int device_count = (int) szParamDataBytes/ sizeof(cl_device_id);
\r
293 return device_count;
\r
296 void btOpenCLUtils::printDeviceInfo(cl_device_id device)
\r
298 btOpenCLDeviceInfo info;
\r
299 getDeviceInfo(device,info);
\r
301 printf(" CL_DEVICE_NAME: \t\t\t%s\n", info.m_deviceName);
\r
302 printf(" CL_DEVICE_VENDOR: \t\t\t%s\n", info.m_deviceVendor);
\r
303 printf(" CL_DRIVER_VERSION: \t\t\t%s\n", info.m_driverVersion);
\r
305 if( info.m_deviceType & CL_DEVICE_TYPE_CPU )
\r
306 printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_CPU");
\r
307 if( info.m_deviceType & CL_DEVICE_TYPE_GPU )
\r
308 printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_GPU");
\r
309 if( info.m_deviceType & CL_DEVICE_TYPE_ACCELERATOR )
\r
310 printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_ACCELERATOR");
\r
311 if( info.m_deviceType & CL_DEVICE_TYPE_DEFAULT )
\r
312 printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_DEFAULT");
\r
314 printf(" CL_DEVICE_MAX_COMPUTE_UNITS:\t\t%u\n", info.m_computeUnits);
\r
315 printf(" CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:\t%zu\n", info.m_workitemDims);
\r
316 printf(" CL_DEVICE_MAX_WORK_ITEM_SIZES:\t%zu / %zu / %zu \n", info.m_workItemSize[0], info.m_workItemSize[1], info.m_workItemSize[2]);
\r
317 printf(" CL_DEVICE_MAX_WORK_GROUP_SIZE:\t%zu\n", info.m_workgroupSize);
\r
318 printf(" CL_DEVICE_MAX_CLOCK_FREQUENCY:\t%u MHz\n", info.m_clockFrequency);
\r
319 printf(" CL_DEVICE_ADDRESS_BITS:\t\t%u\n", info.m_addressBits);
\r
320 printf(" CL_DEVICE_MAX_MEM_ALLOC_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_maxMemAllocSize/ (1024 * 1024)));
\r
321 printf(" CL_DEVICE_GLOBAL_MEM_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_globalMemSize/ (1024 * 1024)));
\r
322 printf(" CL_DEVICE_ERROR_CORRECTION_SUPPORT:\t%s\n", info.m_errorCorrectionSupport== CL_TRUE ? "yes" : "no");
\r
323 printf(" CL_DEVICE_LOCAL_MEM_TYPE:\t\t%s\n", info.m_localMemType == 1 ? "local" : "global");
\r
324 printf(" CL_DEVICE_LOCAL_MEM_SIZE:\t\t%u KByte\n", (unsigned int)(info.m_localMemSize / 1024));
\r
325 printf(" CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:\t%u KByte\n", (unsigned int)(info.m_constantBufferSize / 1024));
\r
326 if( info.m_queueProperties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE )
\r
327 printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE");
\r
328 if( info.m_queueProperties & CL_QUEUE_PROFILING_ENABLE )
\r
329 printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_PROFILING_ENABLE");
\r
331 printf(" CL_DEVICE_IMAGE_SUPPORT:\t\t%u\n", info.m_imageSupport);
\r
333 printf(" CL_DEVICE_MAX_READ_IMAGE_ARGS:\t%u\n", info.m_maxReadImageArgs);
\r
334 printf(" CL_DEVICE_MAX_WRITE_IMAGE_ARGS:\t%u\n", info.m_maxWriteImageArgs);
\r
335 printf("\n CL_DEVICE_IMAGE <dim>");
\r
336 printf("\t\t\t2D_MAX_WIDTH\t %zu\n", info.m_image2dMaxWidth);
\r
337 printf("\t\t\t\t\t2D_MAX_HEIGHT\t %zu\n", info.m_image2dMaxHeight);
\r
338 printf("\t\t\t\t\t3D_MAX_WIDTH\t %zu\n", info.m_image3dMaxWidth);
\r
339 printf("\t\t\t\t\t3D_MAX_HEIGHT\t %zu\n", info.m_image3dMaxHeight);
\r
340 printf("\t\t\t\t\t3D_MAX_DEPTH\t %zu\n", info.m_image3dMaxDepth);
\r
341 if (info.m_deviceExtensions != 0)
\r
342 printf("\n CL_DEVICE_EXTENSIONS:%s\n",info.m_deviceExtensions);
\r
344 printf(" CL_DEVICE_EXTENSIONS: None\n");
\r
345 printf(" CL_DEVICE_PREFERRED_VECTOR_WIDTH_<t>\t");
\r
346 printf("CHAR %u, SHORT %u, INT %u,LONG %u, FLOAT %u, DOUBLE %u\n\n\n",
\r
347 info.m_vecWidthChar, info.m_vecWidthShort, info.m_vecWidthInt, info.m_vecWidthLong,info.m_vecWidthFloat, info.m_vecWidthDouble);
\r
352 void btOpenCLUtils::getDeviceInfo(cl_device_id device, btOpenCLDeviceInfo& info)
\r
356 clGetDeviceInfo(device, CL_DEVICE_NAME, BT_MAX_STRING_LENGTH, &info.m_deviceName, NULL);
\r
358 // CL_DEVICE_VENDOR
\r
359 clGetDeviceInfo(device, CL_DEVICE_VENDOR, BT_MAX_STRING_LENGTH, &info.m_deviceVendor, NULL);
\r
361 // CL_DRIVER_VERSION
\r
362 clGetDeviceInfo(device, CL_DRIVER_VERSION, BT_MAX_STRING_LENGTH, &info.m_driverVersion, NULL);
\r
365 clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(cl_device_type), &info.m_deviceType, NULL);
\r
367 // CL_DEVICE_MAX_COMPUTE_UNITS
\r
368 clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(info.m_computeUnits), &info.m_computeUnits, NULL);
\r
370 // CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
\r
371 clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(info.m_workitemDims), &info.m_workitemDims, NULL);
\r
373 // CL_DEVICE_MAX_WORK_ITEM_SIZES
\r
374 clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(info.m_workItemSize), &info.m_workItemSize, NULL);
\r
376 // CL_DEVICE_MAX_WORK_GROUP_SIZE
\r
377 clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(info.m_workgroupSize), &info.m_workgroupSize, NULL);
\r
379 // CL_DEVICE_MAX_CLOCK_FREQUENCY
\r
380 clGetDeviceInfo(device, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(info.m_clockFrequency), &info.m_clockFrequency, NULL);
\r
382 // CL_DEVICE_ADDRESS_BITS
\r
383 clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(info.m_addressBits), &info.m_addressBits, NULL);
\r
385 // CL_DEVICE_MAX_MEM_ALLOC_SIZE
\r
386 clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(info.m_maxMemAllocSize), &info.m_maxMemAllocSize, NULL);
\r
388 // CL_DEVICE_GLOBAL_MEM_SIZE
\r
389 clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(info.m_globalMemSize), &info.m_globalMemSize, NULL);
\r
391 // CL_DEVICE_ERROR_CORRECTION_SUPPORT
\r
392 clGetDeviceInfo(device, CL_DEVICE_ERROR_CORRECTION_SUPPORT, sizeof(info.m_errorCorrectionSupport), &info.m_errorCorrectionSupport, NULL);
\r
394 // CL_DEVICE_LOCAL_MEM_TYPE
\r
395 clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_TYPE, sizeof(info.m_localMemType), &info.m_localMemType, NULL);
\r
397 // CL_DEVICE_LOCAL_MEM_SIZE
\r
398 clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(info.m_localMemSize), &info.m_localMemSize, NULL);
\r
400 // CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE
\r
401 clGetDeviceInfo(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof(info.m_constantBufferSize), &info.m_constantBufferSize, NULL);
\r
403 // CL_DEVICE_QUEUE_PROPERTIES
\r
404 clGetDeviceInfo(device, CL_DEVICE_QUEUE_PROPERTIES, sizeof(info.m_queueProperties), &info.m_queueProperties, NULL);
\r
406 // CL_DEVICE_IMAGE_SUPPORT
\r
407 clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT, sizeof(info.m_imageSupport), &info.m_imageSupport, NULL);
\r
409 // CL_DEVICE_MAX_READ_IMAGE_ARGS
\r
410 clGetDeviceInfo(device, CL_DEVICE_MAX_READ_IMAGE_ARGS, sizeof(info.m_maxReadImageArgs), &info.m_maxReadImageArgs, NULL);
\r
412 // CL_DEVICE_MAX_WRITE_IMAGE_ARGS
\r
413 clGetDeviceInfo(device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, sizeof(info.m_maxWriteImageArgs), &info.m_maxWriteImageArgs, NULL);
\r
415 // 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
\r
416 clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &info.m_image2dMaxWidth, NULL);
\r
417 clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), &info.m_image2dMaxHeight, NULL);
\r
418 clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof(size_t), &info.m_image3dMaxWidth, NULL);
\r
419 clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof(size_t), &info.m_image3dMaxHeight, NULL);
\r
420 clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &info.m_image3dMaxDepth, NULL);
\r
422 // CL_DEVICE_EXTENSIONS: get device extensions, and if any then parse & log the string onto separate lines
\r
423 clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, BT_MAX_STRING_LENGTH, &info.m_deviceExtensions, NULL);
\r
425 // CL_DEVICE_PREFERRED_VECTOR_WIDTH_<type>
\r
426 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &info.m_vecWidthChar, NULL);
\r
427 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, sizeof(cl_uint), &info.m_vecWidthShort, NULL);
\r
428 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), &info.m_vecWidthInt, NULL);
\r
429 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, sizeof(cl_uint), &info.m_vecWidthLong, NULL);
\r
430 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof(cl_uint), &info.m_vecWidthFloat, NULL);
\r
431 clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), &info.m_vecWidthDouble, NULL);
\r
434 static char* strip1(char* name, const char* pattern,int* numOccurences=0)
\r
436 size_t const patlen = strlen(pattern);
\r
439 // find how many times the pattern occurs in the original string
\r
440 for (oriptr = name; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
\r
443 (*numOccurences)++;
\r
447 static const char* strip2(const char* name, const char* pattern,int* numOccurences=0)
\r
449 size_t const patlen = strlen(pattern);
\r
450 const char * oriptr;
\r
451 const char * patloc;
\r
452 // find how many times the pattern occurs in the original string
\r
453 for (oriptr = name; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
\r
456 (*numOccurences)++;
\r
461 cl_program btOpenCLUtils::compileCLProgramFromString(cl_context clContext, cl_device_id device, const char* kernelSource, cl_int* pErrNum, const char* additionalMacros)
\r
464 cl_int localErrNum;
\r
465 size_t program_length = strlen(kernelSource);
\r
467 cl_program m_cpProgram = clCreateProgramWithSource(clContext, 1, (const char**)&kernelSource, &program_length, &localErrNum);
\r
468 if (localErrNum!= CL_SUCCESS)
\r
471 *pErrNum = localErrNum;
\r
475 // Build the program with 'mad' Optimization option
\r
479 char* flags = "-cl-mad-enable -DMAC -DGUID_ARG";
\r
481 //const char* flags = "-DGUID_ARG= -fno-alias";
\r
482 const char* flags = "-DGUID_ARG= ";
\r
485 char* compileFlags = new char[strlen(additionalMacros) + strlen(flags) + 5];
\r
486 sprintf(compileFlags, "%s %s", flags, additionalMacros);
\r
487 localErrNum = clBuildProgram(m_cpProgram, 1, &device, compileFlags, NULL, NULL);
\r
488 if (localErrNum!= CL_SUCCESS)
\r
491 size_t ret_val_size;
\r
492 clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
\r
493 build_log = new char[ret_val_size+1];
\r
494 clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
\r
496 // to be carefully, terminate with \0
\r
497 // there's no information in the reference whether the string is 0 terminated or not
\r
498 build_log[ret_val_size] = '\0';
\r
501 printf("Error in clBuildProgram, Line %u in file %s, Log: \n%s\n !!!\n\n", __LINE__, __FILE__, build_log);
\r
502 delete[] build_log;
\r
504 *pErrNum = localErrNum;
\r
507 delete[] compileFlags;
\r
508 return m_cpProgram;
\r
511 cl_program btOpenCLUtils::compileCLProgramFromFile(cl_context clContext, cl_device_id device, cl_int* pErrNum, const char* additionalMacros , const char* clFileNameForCaching)
\r
514 cl_program m_cpProgram=0;
\r
516 char binaryFileName[522];
\r
518 if (clFileNameForCaching)
\r
521 char deviceName[256];
\r
522 char driverVersion[256];
\r
523 clGetDeviceInfo(device, CL_DEVICE_NAME, 256, &deviceName, NULL);
\r
524 clGetDeviceInfo(device, CL_DRIVER_VERSION, 256, &driverVersion, NULL);
\r
527 const char* strippedName = strip2(clFileNameForCaching,"\\");
\r
528 strippedName = strip2(strippedName,"/");
\r
529 #ifdef BT_USE_CACHE_DIR
\r
530 sprintf_s(binaryFileName,"cache/%s.%s.%s.bin",strippedName, deviceName,driverVersion );
\r
532 sprintf_s(binaryFileName,"%s.%s.%s.bin",strippedName, deviceName,driverVersion );
\r
535 //printf("searching for %s\n", binaryFileName);
\r
537 bool fileUpToDate = false;
\r
538 bool binaryFileValid=false;
\r
540 FILETIME modtimeBinary;
\r
542 #ifdef BT_USE_CACHE_DIR
\r
543 CreateDirectory("cache",0);
\r
544 #endif //BT_USE_CACHE_DIR
\r
547 HANDLE binaryFileHandle = CreateFile(binaryFileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
\r
548 if (binaryFileHandle ==INVALID_HANDLE_VALUE)
\r
551 errorCode = GetLastError();
\r
554 case ERROR_FILE_NOT_FOUND:
\r
556 printf("\nCached file not found %s\n", binaryFileName);
\r
559 case ERROR_PATH_NOT_FOUND:
\r
561 printf("\nCached file path not found %s\n", binaryFileName);
\r
566 printf("\nFailed reading cached file with errorCode = %d\n", errorCode);
\r
571 if (GetFileTime(binaryFileHandle, NULL, NULL, &modtimeBinary)==0)
\r
574 errorCode = GetLastError();
\r
575 printf("\nGetFileTime errorCode = %d\n", errorCode);
\r
578 binaryFileValid = true;
\r
580 CloseHandle(binaryFileHandle);
\r
583 if (binaryFileValid)
\r
585 HANDLE srcFileHandle = CreateFile(clFileNameForCaching,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
\r
586 if (srcFileHandle!=INVALID_HANDLE_VALUE)
\r
588 FILETIME modtimeSrc;
\r
589 if (GetFileTime(srcFileHandle, NULL, NULL, &modtimeSrc)==0)
\r
592 errorCode = GetLastError();
\r
593 printf("\nGetFileTime errorCode = %d\n", errorCode);
\r
595 if ( ( modtimeSrc.dwHighDateTime < modtimeBinary.dwHighDateTime)
\r
596 ||(( modtimeSrc.dwHighDateTime == modtimeBinary.dwHighDateTime)&&(modtimeSrc.dwLowDateTime <= modtimeBinary.dwLowDateTime)))
\r
601 printf("\nCached binary file out-of-date (%s)\n",binaryFileName);
\r
603 CloseHandle(srcFileHandle);
\r
608 errorCode = GetLastError();
\r
611 case ERROR_FILE_NOT_FOUND:
\r
613 printf("\nSrc file not found %s\n", clFileNameForCaching);
\r
616 case ERROR_PATH_NOT_FOUND:
\r
618 printf("\nSrc path not found %s\n", clFileNameForCaching);
\r
623 printf("\nnSrc file reading errorCode = %d\n", errorCode);
\r
627 //we should make sure the src file exists so we can verify the timestamp with binary
\r
628 fileUpToDate = false;
\r
637 FILE* file = fopen(binaryFileName, "rb");
\r
640 fseek( file, 0L, SEEK_END );
\r
641 size_t binarySize = ftell( file );
\r
643 char* binary = new char[binarySize];
\r
644 fread( binary, sizeof(char), binarySize, file );
\r
647 m_cpProgram = clCreateProgramWithBinary( clContext, 1,&device, &binarySize, (const unsigned char**)&binary, 0, &status );
\r
648 btAssert( status == CL_SUCCESS );
\r
649 status = clBuildProgram( m_cpProgram, 1, &device, additionalMacros, 0, 0 );
\r
650 btAssert( status == CL_SUCCESS );
\r
652 if( status != CL_SUCCESS )
\r
655 size_t ret_val_size;
\r
656 clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
\r
657 build_log = new char[ret_val_size+1];
\r
658 clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
\r
659 build_log[ret_val_size] = '\0';
\r
660 printf("%s\n", build_log);
\r
675 FILE* file = fopen(clFileNameForCaching, "r");
\r
678 fseek( file, 0L, SEEK_END );
\r
679 size_t fileSize= ftell( file );
\r
681 char* kernelSource2 = new char[fileSize+1];
\r
682 fread( kernelSource2, sizeof(char), fileSize, file );
\r
684 kernelSource2[fileSize]=0;
\r
685 int numOccurences = 0;
\r
686 ///patch/remove the MSTRINGIFY( and );
\r
687 char* kernelSource = strip1(kernelSource2,"MSTRINGIFY(",&numOccurences);
\r
688 int newlen = strlen(kernelSource);
\r
695 if (kernelSource[i] == ';')
\r
697 kernelSource[i] = 0;//' ';
\r
703 if (kernelSource[i] == ')')
\r
705 kernelSource[i] = 0;//' ';
\r
711 m_cpProgram = compileCLProgramFromString(clContext,device,kernelSource,pErrNum,additionalMacros);
\r
713 if( clFileNameForCaching )
\r
714 { // write to binary
\r
716 cl_uint numAssociatedDevices;
\r
717 status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_NUM_DEVICES, sizeof(cl_uint), &numAssociatedDevices, 0 );
\r
718 btAssert( status == CL_SUCCESS );
\r
719 if (numAssociatedDevices==1)
\r
723 status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binarySize, 0 );
\r
724 btAssert( status == CL_SUCCESS );
\r
726 char* binary = new char[binarySize];
\r
728 status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARIES, sizeof(char*), &binary, 0 );
\r
729 btAssert( status == CL_SUCCESS );
\r
732 FILE* file = fopen(binaryFileName, "wb");
\r
735 fwrite( binary, sizeof(char), binarySize, file );
\r
739 printf("cannot write file %s\n", binaryFileName);
\r
749 return m_cpProgram;
\r
753 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 )
\r
755 printf("compiling kernel %s ",kernelName);
\r
757 cl_int localErrNum;
\r
758 //size_t program_length = strlen(kernelSource);
\r
761 cl_program m_cpProgram = prog;
\r
764 m_cpProgram = compileCLProgramFromString(clContext,device,kernelSource,pErrNum, additionalMacros);
\r
768 // Create the kernel
\r
769 kernel = clCreateKernel(m_cpProgram, kernelName, &localErrNum);
\r
770 if (localErrNum != CL_SUCCESS)
\r
772 printf("Error in clCreateKernel, Line %u in file %s, cannot find kernel function %s !!!\n\n", __LINE__, __FILE__, kernelName);
\r
774 *pErrNum = localErrNum;
\r
778 if (!prog && m_cpProgram)
\r
780 clReleaseProgram(m_cpProgram);
\r
782 printf("ready. \n");
\r
786 *pErrNum = CL_SUCCESS;
\r