Bullet Collision Detection & Physics Library

MiniCL.cpp

Go to the documentation of this file.
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 }