|
Bullet Collision Detection & Physics Library
|
00001 /* 00002 Copyright (C) 2010 Sony Computer Entertainment Inc. 00003 All rights reserved. 00004 00005 This software is provided 'as-is', without any express or implied warranty. 00006 In no event will the authors be held liable for any damages arising from the use of this software. 00007 Permission is granted to anyone to use this software for any purpose, 00008 including commercial applications, and to alter it and redistribute it freely, 00009 subject to the following restrictions: 00010 00011 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. 00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00013 3. This notice may not be removed or altered from any source distribution. 00014 00015 */ 00016 00017 00018 #include "MiniCL/cl.h" 00019 #define __PHYSICS_COMMON_H__ 1 00020 #ifdef _WIN32 00021 #include "BulletMultiThreaded/Win32ThreadSupport.h" 00022 #endif 00023 00024 #include "BulletMultiThreaded/PlatformDefinitions.h" 00025 #ifdef USE_PTHREADS 00026 #include "BulletMultiThreaded/PosixThreadSupport.h" 00027 #endif 00028 00029 00030 #include "BulletMultiThreaded/SequentialThreadSupport.h" 00031 #include "MiniCLTaskScheduler.h" 00032 #include "MiniCLTask/MiniCLTask.h" 00033 #include "LinearMath/btMinMax.h" 00034 #include <stdio.h> 00035 00036 //#define DEBUG_MINICL_KERNELS 1 00037 00038 static const char* spPlatformID = "MiniCL, SCEA"; 00039 static const char* spDriverVersion= "1.0"; 00040 00041 CL_API_ENTRY cl_int CL_API_CALL clGetPlatformIDs( 00042 cl_uint num_entries, 00043 cl_platform_id * platforms, 00044 cl_uint * num_platforms ) CL_API_SUFFIX__VERSION_1_0 00045 { 00046 if(platforms != NULL) 00047 { 00048 if(num_entries <= 0) 00049 { 00050 return CL_INVALID_VALUE; 00051 } 00052 *((const char**)platforms) = spPlatformID; 00053 } 00054 if(num_platforms != NULL) 00055 { 00056 *num_platforms = 1; 00057 } 00058 return CL_SUCCESS; 00059 } 00060 00061 00062 CL_API_ENTRY cl_int CL_API_CALL clGetPlatformInfo( 00063 cl_platform_id platform, 00064 cl_platform_info param_name, 00065 size_t param_value_size, 00066 void * param_value, 00067 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0 00068 { 00069 char* pId = (char*)platform; 00070 if(strcmp(pId, spPlatformID)) 00071 { 00072 return CL_INVALID_PLATFORM; 00073 } 00074 switch(param_name) 00075 { 00076 case CL_PLATFORM_VERSION: 00077 { 00078 if(param_value_size < (strlen(spDriverVersion) + 1)) 00079 { 00080 return CL_INVALID_VALUE; 00081 } 00082 strcpy((char*)param_value, spDriverVersion); 00083 if(param_value_size_ret != NULL) 00084 { 00085 *param_value_size_ret = strlen(spDriverVersion) + 1; 00086 } 00087 break; 00088 } 00089 case CL_PLATFORM_NAME: 00090 case CL_PLATFORM_VENDOR : 00091 if(param_value_size < (strlen(spPlatformID) + 1)) 00092 { 00093 return CL_INVALID_VALUE; 00094 } 00095 strcpy((char*)param_value, spPlatformID); 00096 if(param_value_size_ret != NULL) 00097 { 00098 *param_value_size_ret = strlen(spPlatformID) + 1; 00099 } 00100 break; 00101 default : 00102 return CL_INVALID_VALUE; 00103 } 00104 return CL_SUCCESS; 00105 } 00106 00107 00108 00109 00110 CL_API_ENTRY cl_int CL_API_CALL clGetDeviceInfo( 00111 cl_device_id device , 00112 cl_device_info param_name , 00113 size_t param_value_size , 00114 void * param_value , 00115 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0 00116 { 00117 00118 switch (param_name) 00119 { 00120 case CL_DEVICE_NAME: 00121 { 00122 char deviceName[] = "MiniCL CPU"; 00123 unsigned int nameLen = (unsigned int)strlen(deviceName)+1; 00124 btAssert(param_value_size>strlen(deviceName)); 00125 if (nameLen < param_value_size) 00126 { 00127 const char* cpuName = "MiniCL CPU"; 00128 sprintf((char*)param_value,"%s",cpuName); 00129 } else 00130 { 00131 printf("error: param_value_size should be at least %d, but it is %d\n",nameLen,param_value_size); 00132 return CL_INVALID_VALUE; 00133 } 00134 break; 00135 } 00136 case CL_DEVICE_TYPE: 00137 { 00138 if (param_value_size>=sizeof(cl_device_type)) 00139 { 00140 cl_device_type* deviceType = (cl_device_type*)param_value; 00141 *deviceType = CL_DEVICE_TYPE_CPU; 00142 } else 00143 { 00144 printf("error: param_value_size should be at least %d\n",sizeof(cl_device_type)); 00145 return CL_INVALID_VALUE; 00146 } 00147 break; 00148 } 00149 case CL_DEVICE_MAX_COMPUTE_UNITS: 00150 { 00151 if (param_value_size>=sizeof(cl_uint)) 00152 { 00153 cl_uint* numUnits = (cl_uint*)param_value; 00154 *numUnits= 4; 00155 } else 00156 { 00157 printf("error: param_value_size should be at least %d\n",sizeof(cl_uint)); 00158 return CL_INVALID_VALUE; 00159 } 00160 00161 break; 00162 } 00163 case CL_DEVICE_MAX_WORK_ITEM_SIZES: 00164 { 00165 size_t workitem_size[3]; 00166 00167 if (param_value_size>=sizeof(workitem_size)) 00168 { 00169 size_t* workItemSize = (size_t*)param_value; 00170 workItemSize[0] = 64; 00171 workItemSize[1] = 24; 00172 workItemSize[2] = 16; 00173 } else 00174 { 00175 printf("error: param_value_size should be at least %d\n",sizeof(cl_uint)); 00176 return CL_INVALID_VALUE; 00177 } 00178 break; 00179 } 00180 case CL_DEVICE_MAX_CLOCK_FREQUENCY: 00181 { 00182 cl_uint* clock_frequency = (cl_uint*)param_value; 00183 *clock_frequency = 3*1024; 00184 break; 00185 } 00186 00187 case CL_DEVICE_VENDOR : 00188 { 00189 if(param_value_size < (strlen(spPlatformID) + 1)) 00190 { 00191 return CL_INVALID_VALUE; 00192 } 00193 strcpy((char*)param_value, spPlatformID); 00194 if(param_value_size_ret != NULL) 00195 { 00196 *param_value_size_ret = strlen(spPlatformID) + 1; 00197 } 00198 break; 00199 } 00200 case CL_DRIVER_VERSION: 00201 { 00202 if(param_value_size < (strlen(spDriverVersion) + 1)) 00203 { 00204 return CL_INVALID_VALUE; 00205 } 00206 strcpy((char*)param_value, spDriverVersion); 00207 if(param_value_size_ret != NULL) 00208 { 00209 *param_value_size_ret = strlen(spDriverVersion) + 1; 00210 } 00211 00212 break; 00213 } 00214 case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: 00215 { 00216 cl_uint* maxDimensions = (cl_uint*)param_value; 00217 *maxDimensions = 1; 00218 break; 00219 } 00220 case CL_DEVICE_MAX_WORK_GROUP_SIZE: 00221 { 00222 cl_uint* maxWorkGroupSize = (cl_uint*)param_value; 00223 *maxWorkGroupSize = 128;//1; 00224 break; 00225 } 00226 case CL_DEVICE_ADDRESS_BITS: 00227 { 00228 cl_uint* addressBits = (cl_uint*)param_value; 00229 *addressBits= 32; //@todo: should this be 64 for 64bit builds? 00230 break; 00231 } 00232 case CL_DEVICE_MAX_MEM_ALLOC_SIZE: 00233 { 00234 cl_ulong* maxMemAlloc = (cl_ulong*)param_value; 00235 *maxMemAlloc= 512*1024*1024; //this "should be enough for everyone" ? 00236 break; 00237 } 00238 case CL_DEVICE_GLOBAL_MEM_SIZE: 00239 { 00240 cl_ulong* maxMemAlloc = (cl_ulong*)param_value; 00241 *maxMemAlloc= 1024*1024*1024; //this "should be enough for everyone" ? 00242 break; 00243 } 00244 00245 case CL_DEVICE_ERROR_CORRECTION_SUPPORT: 00246 { 00247 cl_bool* error_correction_support = (cl_bool*)param_value; 00248 *error_correction_support = CL_FALSE; 00249 break; 00250 } 00251 00252 case CL_DEVICE_LOCAL_MEM_TYPE: 00253 { 00254 cl_device_local_mem_type* local_mem_type = (cl_device_local_mem_type*)param_value; 00255 *local_mem_type = CL_GLOBAL; 00256 break; 00257 } 00258 case CL_DEVICE_LOCAL_MEM_SIZE: 00259 { 00260 cl_ulong* localmem = (cl_ulong*) param_value; 00261 *localmem = 32*1024; 00262 break; 00263 } 00264 00265 case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: 00266 { 00267 cl_ulong* localmem = (cl_ulong*) param_value; 00268 *localmem = 64*1024; 00269 break; 00270 } 00271 case CL_DEVICE_QUEUE_PROPERTIES: 00272 { 00273 cl_command_queue_properties* queueProp = (cl_command_queue_properties*) param_value; 00274 memset(queueProp,0,param_value_size); 00275 00276 break; 00277 } 00278 case CL_DEVICE_IMAGE_SUPPORT: 00279 { 00280 cl_bool* imageSupport = (cl_bool*) param_value; 00281 *imageSupport = CL_FALSE; 00282 break; 00283 } 00284 00285 case CL_DEVICE_MAX_WRITE_IMAGE_ARGS: 00286 case CL_DEVICE_MAX_READ_IMAGE_ARGS: 00287 { 00288 cl_uint* imageArgs = (cl_uint*) param_value; 00289 *imageArgs = 0; 00290 break; 00291 } 00292 case CL_DEVICE_IMAGE3D_MAX_DEPTH: 00293 case CL_DEVICE_IMAGE3D_MAX_HEIGHT: 00294 case CL_DEVICE_IMAGE2D_MAX_HEIGHT: 00295 case CL_DEVICE_IMAGE3D_MAX_WIDTH: 00296 case CL_DEVICE_IMAGE2D_MAX_WIDTH: 00297 { 00298 size_t* maxSize = (size_t*) param_value; 00299 *maxSize = 0; 00300 break; 00301 } 00302 00303 case CL_DEVICE_EXTENSIONS: 00304 { 00305 char* extensions = (char*) param_value; 00306 *extensions = 0; 00307 break; 00308 } 00309 00310 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: 00311 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: 00312 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: 00313 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT: 00314 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: 00315 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: 00316 { 00317 cl_uint* width = (cl_uint*) param_value; 00318 *width = 1; 00319 break; 00320 } 00321 00322 default: 00323 { 00324 printf("error: unsupported param_name:%d\n",param_name); 00325 } 00326 } 00327 00328 00329 return 0; 00330 } 00331 00332 CL_API_ENTRY cl_int CL_API_CALL clReleaseMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0 00333 { 00334 return 0; 00335 } 00336 00337 00338 00339 CL_API_ENTRY cl_int CL_API_CALL clReleaseCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0 00340 { 00341 return 0; 00342 } 00343 00344 CL_API_ENTRY cl_int CL_API_CALL clReleaseProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0 00345 { 00346 return 0; 00347 } 00348 00349 CL_API_ENTRY cl_int CL_API_CALL clReleaseKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0 00350 { 00351 return 0; 00352 } 00353 00354 00355 // Enqueued Commands APIs 00356 CL_API_ENTRY cl_int CL_API_CALL clEnqueueReadBuffer(cl_command_queue command_queue , 00357 cl_mem buffer , 00358 cl_bool /* blocking_read */, 00359 size_t offset , 00360 size_t cb , 00361 void * ptr , 00362 cl_uint /* num_events_in_wait_list */, 00363 const cl_event * /* event_wait_list */, 00364 cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0 00365 { 00366 MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue; 00367 00369 scheduler->flush(); 00370 00371 memcpy(ptr,(char*)buffer + offset,cb); 00372 return 0; 00373 } 00374 00375 00376 CL_API_ENTRY cl_int clGetProgramBuildInfo(cl_program /* program */, 00377 cl_device_id /* device */, 00378 cl_program_build_info /* param_name */, 00379 size_t /* param_value_size */, 00380 void * /* param_value */, 00381 size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0 00382 { 00383 00384 return 0; 00385 } 00386 00387 00388 // Program Object APIs 00389 CL_API_ENTRY cl_program 00390 clCreateProgramWithSource(cl_context context , 00391 cl_uint /* count */, 00392 const char ** /* strings */, 00393 const size_t * /* lengths */, 00394 cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 00395 { 00396 *errcode_ret = CL_SUCCESS; 00397 return (cl_program)context; 00398 } 00399 00400 CL_API_ENTRY cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue command_queue , 00401 cl_mem buffer , 00402 cl_bool /* blocking_read */, 00403 size_t offset, 00404 size_t cb , 00405 const void * ptr , 00406 cl_uint /* num_events_in_wait_list */, 00407 const cl_event * /* event_wait_list */, 00408 cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0 00409 { 00410 MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue; 00411 00413 scheduler->flush(); 00414 00415 memcpy((char*)buffer + offset, ptr,cb); 00416 return 0; 00417 } 00418 00419 CL_API_ENTRY cl_int CL_API_CALL clFlush(cl_command_queue command_queue) 00420 { 00421 MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue; 00423 scheduler->flush(); 00424 return 0; 00425 } 00426 00427 00428 CL_API_ENTRY cl_int CL_API_CALL clEnqueueNDRangeKernel(cl_command_queue /* command_queue */, 00429 cl_kernel clKernel , 00430 cl_uint work_dim , 00431 const size_t * /* global_work_offset */, 00432 const size_t * global_work_size , 00433 const size_t * /* local_work_size */, 00434 cl_uint /* num_events_in_wait_list */, 00435 const cl_event * /* event_wait_list */, 00436 cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0 00437 { 00438 00439 00440 MiniCLKernel* kernel = (MiniCLKernel*) clKernel; 00441 for (unsigned int ii=0;ii<work_dim;ii++) 00442 { 00443 int maxTask = kernel->m_scheduler->getMaxNumOutstandingTasks(); 00444 int numWorkItems = global_work_size[ii]; 00445 00446 // //at minimum 64 work items per task 00447 // int numWorkItemsPerTask = btMax(64,numWorkItems / maxTask); 00448 int numWorkItemsPerTask = numWorkItems / maxTask; 00449 if (!numWorkItemsPerTask) numWorkItemsPerTask = 1; 00450 00451 for (int t=0;t<numWorkItems;) 00452 { 00453 //Performance Hint: tweak this number during benchmarking 00454 int endIndex = (t+numWorkItemsPerTask) < numWorkItems ? t+numWorkItemsPerTask : numWorkItems; 00455 kernel->m_scheduler->issueTask(t, endIndex, kernel); 00456 t = endIndex; 00457 } 00458 } 00459 /* 00460 00461 void* bla = 0; 00462 00463 scheduler->issueTask(bla,2,3); 00464 scheduler->flush(); 00465 00466 */ 00467 00468 return 0; 00469 } 00470 00471 #define LOCAL_BUF_SIZE 32768 00472 static int sLocalMemBuf[LOCAL_BUF_SIZE * 4 + 16]; 00473 static int* spLocalBufCurr = NULL; 00474 static int sLocalBufUsed = LOCAL_BUF_SIZE; // so it will be reset at the first call 00475 static void* localBufMalloc(int size) 00476 { 00477 int size16 = (size + 15) >> 4; // in 16-byte units 00478 if((sLocalBufUsed + size16) > LOCAL_BUF_SIZE) 00479 { // reset 00480 spLocalBufCurr = sLocalMemBuf; 00481 while((unsigned long)spLocalBufCurr & 0x0F) spLocalBufCurr++; // align to 16 bytes 00482 sLocalBufUsed = 0; 00483 } 00484 void* ret = spLocalBufCurr; 00485 spLocalBufCurr += size16 * 4; 00486 sLocalBufUsed += size; 00487 return ret; 00488 } 00489 00490 00491 00492 CL_API_ENTRY cl_int CL_API_CALL clSetKernelArg(cl_kernel clKernel , 00493 cl_uint arg_index , 00494 size_t arg_size , 00495 const void * arg_value ) CL_API_SUFFIX__VERSION_1_0 00496 { 00497 MiniCLKernel* kernel = (MiniCLKernel* ) clKernel; 00498 btAssert(arg_size <= MINICL_MAX_ARGLENGTH); 00499 if (arg_index>MINI_CL_MAX_ARG) 00500 { 00501 printf("error: clSetKernelArg arg_index (%u) exceeds %u\n",arg_index,MINI_CL_MAX_ARG); 00502 } else 00503 { 00504 if (arg_size>MINICL_MAX_ARGLENGTH) 00505 //if (arg_size != MINICL_MAX_ARGLENGTH) 00506 { 00507 printf("error: clSetKernelArg argdata too large: %zu (maximum is %zu)\n",arg_size,MINICL_MAX_ARGLENGTH); 00508 } 00509 else 00510 { 00511 if(arg_value == NULL) 00512 { // this is only for __local memory qualifier 00513 void* ptr = localBufMalloc(arg_size); 00514 kernel->m_argData[arg_index] = ptr; 00515 } 00516 else 00517 { 00518 memcpy(&(kernel->m_argData[arg_index]), arg_value, arg_size); 00519 } 00520 kernel->m_argSizes[arg_index] = arg_size; 00521 if(arg_index >= kernel->m_numArgs) 00522 { 00523 kernel->m_numArgs = arg_index + 1; 00524 kernel->updateLauncher(); 00525 } 00526 } 00527 } 00528 return 0; 00529 } 00530 00531 // Kernel Object APIs 00532 CL_API_ENTRY cl_kernel CL_API_CALL clCreateKernel(cl_program program , 00533 const char * kernel_name , 00534 cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 00535 { 00536 MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) program; 00537 MiniCLKernel* kernel = new MiniCLKernel(); 00538 int nameLen = strlen(kernel_name); 00539 if(nameLen >= MINI_CL_MAX_KERNEL_NAME) 00540 { 00541 *errcode_ret = CL_INVALID_KERNEL_NAME; 00542 return NULL; 00543 } 00544 strcpy(kernel->m_name, kernel_name); 00545 kernel->m_numArgs = 0; 00546 00547 //kernel->m_kernelProgramCommandId = scheduler->findProgramCommandIdByName(kernel_name); 00548 //if (kernel->m_kernelProgramCommandId>=0) 00549 //{ 00550 // *errcode_ret = CL_SUCCESS; 00551 //} else 00552 //{ 00553 // *errcode_ret = CL_INVALID_KERNEL_NAME; 00554 //} 00555 kernel->m_scheduler = scheduler; 00556 if(kernel->registerSelf() == NULL) 00557 { 00558 *errcode_ret = CL_INVALID_KERNEL_NAME; 00559 return NULL; 00560 } 00561 else 00562 { 00563 *errcode_ret = CL_SUCCESS; 00564 } 00565 00566 return (cl_kernel)kernel; 00567 00568 } 00569 00570 00571 CL_API_ENTRY cl_int CL_API_CALL clBuildProgram(cl_program /* program */, 00572 cl_uint /* num_devices */, 00573 const cl_device_id * /* device_list */, 00574 const char * /* options */, 00575 void (*pfn_notify)(cl_program /* program */, void * /* user_data */), 00576 void * /* user_data */) CL_API_SUFFIX__VERSION_1_0 00577 { 00578 return CL_SUCCESS; 00579 } 00580 00581 CL_API_ENTRY cl_program CL_API_CALL clCreateProgramWithBinary(cl_context context , 00582 cl_uint /* num_devices */, 00583 const cl_device_id * /* device_list */, 00584 const size_t * /* lengths */, 00585 const unsigned char ** /* binaries */, 00586 cl_int * /* binary_status */, 00587 cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0 00588 { 00589 return (cl_program)context; 00590 } 00591 00592 00593 // Memory Object APIs 00594 CL_API_ENTRY cl_mem CL_API_CALL clCreateBuffer(cl_context /* context */, 00595 cl_mem_flags flags , 00596 size_t size, 00597 void * host_ptr , 00598 cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 00599 { 00600 cl_mem buf = (cl_mem)malloc(size); 00601 if ((flags&CL_MEM_COPY_HOST_PTR) && host_ptr) 00602 { 00603 memcpy(buf,host_ptr,size); 00604 } 00605 *errcode_ret = 0; 00606 return buf; 00607 } 00608 00609 // Command Queue APIs 00610 CL_API_ENTRY cl_command_queue CL_API_CALL clCreateCommandQueue(cl_context context , 00611 cl_device_id /* device */, 00612 cl_command_queue_properties /* properties */, 00613 cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 00614 { 00615 *errcode_ret = 0; 00616 return (cl_command_queue) context; 00617 } 00618 00619 extern CL_API_ENTRY cl_int CL_API_CALL clGetContextInfo(cl_context /* context */, 00620 cl_context_info param_name , 00621 size_t param_value_size , 00622 void * param_value, 00623 size_t * param_value_size_ret ) CL_API_SUFFIX__VERSION_1_0 00624 { 00625 00626 switch (param_name) 00627 { 00628 case CL_CONTEXT_DEVICES: 00629 { 00630 if (!param_value_size) 00631 { 00632 *param_value_size_ret = 13; 00633 } else 00634 { 00635 const char* testName = "MiniCL_Test."; 00636 sprintf((char*)param_value,"%s",testName); 00637 } 00638 break; 00639 }; 00640 default: 00641 { 00642 printf("unsupported\n"); 00643 } 00644 } 00645 00646 return 0; 00647 } 00648 00649 00650 00651 CL_API_ENTRY cl_context CL_API_CALL clCreateContextFromType(const cl_context_properties * /* properties */, 00652 cl_device_type device_type , 00653 void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */, 00654 void * /* user_data */, 00655 cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 00656 { 00657 int maxNumOutstandingTasks = 4; 00658 // int maxNumOutstandingTasks = 2; 00659 // int maxNumOutstandingTasks = 1; 00660 gMiniCLNumOutstandingTasks = maxNumOutstandingTasks; 00661 const int maxNumOfThreadSupports = 8; 00662 static int sUniqueThreadSupportIndex = 0; 00663 static const char* sUniqueThreadSupportName[maxNumOfThreadSupports] = 00664 { 00665 "MiniCL_0", "MiniCL_1", "MiniCL_2", "MiniCL_3", "MiniCL_4", "MiniCL_5", "MiniCL_6", "MiniCL_7" 00666 }; 00667 00668 btThreadSupportInterface* threadSupport = 0; 00669 00670 if (device_type==CL_DEVICE_TYPE_DEBUG) 00671 { 00672 SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory); 00673 threadSupport = new SequentialThreadSupport(stc); 00674 } else 00675 { 00676 00677 #if _WIN32 00678 btAssert(sUniqueThreadSupportIndex < maxNumOfThreadSupports); 00679 const char* bla = "MiniCL"; 00680 threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( 00681 // bla, 00682 sUniqueThreadSupportName[sUniqueThreadSupportIndex++], 00683 processMiniCLTask, //processCollisionTask, 00684 createMiniCLLocalStoreMemory,//createCollisionLocalStoreMemory, 00685 maxNumOutstandingTasks)); 00686 #else 00687 00688 #ifdef USE_PTHREADS 00689 PosixThreadSupport::ThreadConstructionInfo constructionInfo("PosixThreads", 00690 processMiniCLTask, 00691 createMiniCLLocalStoreMemory, 00692 maxNumOutstandingTasks); 00693 threadSupport = new PosixThreadSupport(constructionInfo); 00694 00695 #else 00696 00697 SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory); 00698 threadSupport = new SequentialThreadSupport(stc); 00699 #endif //USE_PTHREADS 00700 #endif 00701 00702 } 00703 00704 00705 MiniCLTaskScheduler* scheduler = new MiniCLTaskScheduler(threadSupport,maxNumOutstandingTasks); 00706 00707 *errcode_ret = 0; 00708 return (cl_context)scheduler; 00709 } 00710 00711 CL_API_ENTRY cl_int CL_API_CALL 00712 clGetDeviceIDs(cl_platform_id /* platform */, 00713 cl_device_type /* device_type */, 00714 cl_uint /* num_entries */, 00715 cl_device_id * /* devices */, 00716 cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0 00717 { 00718 return 0; 00719 } 00720 00721 CL_API_ENTRY cl_context CL_API_CALL 00722 clCreateContext(const cl_context_properties * properties , 00723 cl_uint num_devices , 00724 const cl_device_id * devices , 00725 void (*pfn_notify)(const char *, const void *, size_t, void *), 00726 void * user_data , 00727 cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0 00728 { 00729 00730 return clCreateContextFromType(properties,CL_DEVICE_TYPE_ALL,pfn_notify,user_data,errcode_ret); 00731 } 00732 00733 CL_API_ENTRY cl_int CL_API_CALL clReleaseContext(cl_context context ) CL_API_SUFFIX__VERSION_1_0 00734 { 00735 00736 MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) context; 00737 00738 btThreadSupportInterface* threadSupport = scheduler->getThreadSupportInterface(); 00739 delete scheduler; 00740 delete threadSupport; 00741 00742 return 0; 00743 } 00744 extern CL_API_ENTRY cl_int CL_API_CALL 00745 clFinish(cl_command_queue command_queue ) CL_API_SUFFIX__VERSION_1_0 00746 { 00747 MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue; 00749 scheduler->flush(); 00750 return CL_SUCCESS; 00751 } 00752 00753 extern CL_API_ENTRY cl_int CL_API_CALL 00754 clGetProgramInfo(cl_program /* program */, 00755 cl_program_info /* param_name */, 00756 size_t /* param_value_size */, 00757 void * /* param_value */, 00758 size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0 00759 { 00760 return 0; 00761 } 00762 00763 extern CL_API_ENTRY cl_int CL_API_CALL 00764 clGetKernelWorkGroupInfo(cl_kernel kernel , 00765 cl_device_id /* device */, 00766 cl_kernel_work_group_info wgi/* param_name */, 00767 size_t sz /* param_value_size */, 00768 void * ptr /* param_value */, 00769 size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0 00770 { 00771 if((wgi == CL_KERNEL_WORK_GROUP_SIZE) 00772 &&(sz == sizeof(size_t)) 00773 &&(ptr != NULL)) 00774 { 00775 MiniCLKernel* miniCLKernel = (MiniCLKernel*)kernel; 00776 MiniCLTaskScheduler* scheduler = miniCLKernel->m_scheduler; 00777 *((size_t*)ptr) = scheduler->getMaxNumOutstandingTasks(); 00778 return CL_SUCCESS; 00779 } 00780 else 00781 { 00782 return CL_INVALID_VALUE; 00783 } 00784 }