789 lines
22 KiB
C++
789 lines
22 KiB
C++
/*
|
|
Copyright (C) 2010 Sony Computer Entertainment Inc.
|
|
All rights reserved.
|
|
|
|
This software is provided 'as-is', without any express or implied warranty.
|
|
In no event will the authors be held liable for any damages arising from the use of this software.
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it freely,
|
|
subject to the following restrictions:
|
|
|
|
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.
|
|
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
|
|
*/
|
|
|
|
|
|
#include "MiniCL/cl.h"
|
|
#define __PHYSICS_COMMON_H__ 1
|
|
#ifdef _WIN32
|
|
#include "BulletMultiThreaded/Win32ThreadSupport.h"
|
|
#endif
|
|
|
|
#include "BulletMultiThreaded/PlatformDefinitions.h"
|
|
#ifdef USE_PTHREADS
|
|
#include "BulletMultiThreaded/PosixThreadSupport.h"
|
|
#endif
|
|
|
|
|
|
#include "BulletMultiThreaded/SequentialThreadSupport.h"
|
|
#include "MiniCLTaskScheduler.h"
|
|
#include "MiniCLTask/MiniCLTask.h"
|
|
#include "LinearMath/btMinMax.h"
|
|
#include <stdio.h>
|
|
#include <stddef.h>
|
|
|
|
//#define DEBUG_MINICL_KERNELS 1
|
|
|
|
static const char* spPlatformID = "MiniCL, SCEA";
|
|
static const char* spDriverVersion= "1.0";
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clGetPlatformIDs(
|
|
cl_uint num_entries,
|
|
cl_platform_id * platforms,
|
|
cl_uint * num_platforms ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
if(platforms != NULL)
|
|
{
|
|
if(num_entries <= 0)
|
|
{
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
*((const char**)platforms) = spPlatformID;
|
|
}
|
|
if(num_platforms != NULL)
|
|
{
|
|
*num_platforms = 1;
|
|
}
|
|
return CL_SUCCESS;
|
|
}
|
|
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clGetPlatformInfo(
|
|
cl_platform_id platform,
|
|
cl_platform_info param_name,
|
|
size_t param_value_size,
|
|
void * param_value,
|
|
size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
char* pId = (char*)platform;
|
|
if(strcmp(pId, spPlatformID))
|
|
{
|
|
return CL_INVALID_PLATFORM;
|
|
}
|
|
switch(param_name)
|
|
{
|
|
case CL_PLATFORM_VERSION:
|
|
{
|
|
if(param_value_size < (strlen(spDriverVersion) + 1))
|
|
{
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
strcpy((char*)param_value, spDriverVersion);
|
|
if(param_value_size_ret != NULL)
|
|
{
|
|
*param_value_size_ret = strlen(spDriverVersion) + 1;
|
|
}
|
|
break;
|
|
}
|
|
case CL_PLATFORM_NAME:
|
|
case CL_PLATFORM_VENDOR :
|
|
if(param_value_size < (strlen(spPlatformID) + 1))
|
|
{
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
strcpy((char*)param_value, spPlatformID);
|
|
if(param_value_size_ret != NULL)
|
|
{
|
|
*param_value_size_ret = strlen(spPlatformID) + 1;
|
|
}
|
|
break;
|
|
default :
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
return CL_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clGetDeviceInfo(
|
|
cl_device_id device ,
|
|
cl_device_info param_name ,
|
|
size_t param_value_size ,
|
|
void * param_value ,
|
|
size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
|
|
switch (param_name)
|
|
{
|
|
case CL_DEVICE_NAME:
|
|
{
|
|
char deviceName[] = "MiniCL CPU";
|
|
unsigned int nameLen = (unsigned int)strlen(deviceName)+1;
|
|
btAssert(param_value_size>strlen(deviceName));
|
|
if (nameLen < param_value_size)
|
|
{
|
|
const char* cpuName = "MiniCL CPU";
|
|
sprintf((char*)param_value,"%s",cpuName);
|
|
} else
|
|
{
|
|
printf("error: param_value_size should be at least %d, but it is %zu\n",nameLen,param_value_size);
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
break;
|
|
}
|
|
case CL_DEVICE_TYPE:
|
|
{
|
|
if (param_value_size>=sizeof(cl_device_type))
|
|
{
|
|
cl_device_type* deviceType = (cl_device_type*)param_value;
|
|
*deviceType = CL_DEVICE_TYPE_CPU;
|
|
} else
|
|
{
|
|
printf("error: param_value_size should be at least %zu\n",sizeof(cl_device_type));
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
break;
|
|
}
|
|
case CL_DEVICE_MAX_COMPUTE_UNITS:
|
|
{
|
|
if (param_value_size>=sizeof(cl_uint))
|
|
{
|
|
cl_uint* numUnits = (cl_uint*)param_value;
|
|
*numUnits= 4;
|
|
} else
|
|
{
|
|
printf("error: param_value_size should be at least %zu\n",sizeof(cl_uint));
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case CL_DEVICE_MAX_WORK_ITEM_SIZES:
|
|
{
|
|
size_t workitem_size[3];
|
|
|
|
if (param_value_size>=sizeof(workitem_size))
|
|
{
|
|
size_t* workItemSize = (size_t*)param_value;
|
|
workItemSize[0] = 64;
|
|
workItemSize[1] = 24;
|
|
workItemSize[2] = 16;
|
|
} else
|
|
{
|
|
printf("error: param_value_size should be at least %zu\n",sizeof(cl_uint));
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
break;
|
|
}
|
|
case CL_DEVICE_MAX_CLOCK_FREQUENCY:
|
|
{
|
|
cl_uint* clock_frequency = (cl_uint*)param_value;
|
|
*clock_frequency = 3*1024;
|
|
break;
|
|
}
|
|
|
|
case CL_DEVICE_VENDOR :
|
|
{
|
|
if(param_value_size < (strlen(spPlatformID) + 1))
|
|
{
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
strcpy((char*)param_value, spPlatformID);
|
|
if(param_value_size_ret != NULL)
|
|
{
|
|
*param_value_size_ret = strlen(spPlatformID) + 1;
|
|
}
|
|
break;
|
|
}
|
|
case CL_DRIVER_VERSION:
|
|
{
|
|
if(param_value_size < (strlen(spDriverVersion) + 1))
|
|
{
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
strcpy((char*)param_value, spDriverVersion);
|
|
if(param_value_size_ret != NULL)
|
|
{
|
|
*param_value_size_ret = strlen(spDriverVersion) + 1;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
|
|
{
|
|
cl_uint* maxDimensions = (cl_uint*)param_value;
|
|
*maxDimensions = 1;
|
|
break;
|
|
}
|
|
case CL_DEVICE_MAX_WORK_GROUP_SIZE:
|
|
{
|
|
cl_uint* maxWorkGroupSize = (cl_uint*)param_value;
|
|
*maxWorkGroupSize = 128;//1;
|
|
break;
|
|
}
|
|
case CL_DEVICE_ADDRESS_BITS:
|
|
{
|
|
cl_uint* addressBits = (cl_uint*)param_value;
|
|
*addressBits= 32; //@todo: should this be 64 for 64bit builds?
|
|
break;
|
|
}
|
|
case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
|
|
{
|
|
cl_ulong* maxMemAlloc = (cl_ulong*)param_value;
|
|
*maxMemAlloc= 512*1024*1024; //this "should be enough for everyone" ?
|
|
break;
|
|
}
|
|
case CL_DEVICE_GLOBAL_MEM_SIZE:
|
|
{
|
|
cl_ulong* maxMemAlloc = (cl_ulong*)param_value;
|
|
*maxMemAlloc= 1024*1024*1024; //this "should be enough for everyone" ?
|
|
break;
|
|
}
|
|
|
|
case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
|
|
{
|
|
cl_bool* error_correction_support = (cl_bool*)param_value;
|
|
*error_correction_support = CL_FALSE;
|
|
break;
|
|
}
|
|
|
|
case CL_DEVICE_LOCAL_MEM_TYPE:
|
|
{
|
|
cl_device_local_mem_type* local_mem_type = (cl_device_local_mem_type*)param_value;
|
|
*local_mem_type = CL_GLOBAL;
|
|
break;
|
|
}
|
|
case CL_DEVICE_LOCAL_MEM_SIZE:
|
|
{
|
|
cl_ulong* localmem = (cl_ulong*) param_value;
|
|
*localmem = 32*1024;
|
|
break;
|
|
}
|
|
|
|
case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
|
|
{
|
|
cl_ulong* localmem = (cl_ulong*) param_value;
|
|
*localmem = 64*1024;
|
|
break;
|
|
}
|
|
case CL_DEVICE_QUEUE_PROPERTIES:
|
|
{
|
|
cl_command_queue_properties* queueProp = (cl_command_queue_properties*) param_value;
|
|
memset(queueProp,0,param_value_size);
|
|
|
|
break;
|
|
}
|
|
case CL_DEVICE_IMAGE_SUPPORT:
|
|
{
|
|
cl_bool* imageSupport = (cl_bool*) param_value;
|
|
*imageSupport = CL_FALSE;
|
|
break;
|
|
}
|
|
|
|
case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
|
|
case CL_DEVICE_MAX_READ_IMAGE_ARGS:
|
|
{
|
|
cl_uint* imageArgs = (cl_uint*) param_value;
|
|
*imageArgs = 0;
|
|
break;
|
|
}
|
|
case CL_DEVICE_IMAGE3D_MAX_DEPTH:
|
|
case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
|
|
case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
|
|
case CL_DEVICE_IMAGE3D_MAX_WIDTH:
|
|
case CL_DEVICE_IMAGE2D_MAX_WIDTH:
|
|
{
|
|
size_t* maxSize = (size_t*) param_value;
|
|
*maxSize = 0;
|
|
break;
|
|
}
|
|
|
|
case CL_DEVICE_EXTENSIONS:
|
|
{
|
|
char* extensions = (char*) param_value;
|
|
*extensions = 0;
|
|
break;
|
|
}
|
|
|
|
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
|
|
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
|
|
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
|
|
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
|
|
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
|
|
case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
|
|
{
|
|
cl_uint* width = (cl_uint*) param_value;
|
|
*width = 1;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
printf("error: unsupported param_name:%d\n",param_name);
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clReleaseMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clReleaseCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clReleaseProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clReleaseKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
// Enqueued Commands APIs
|
|
CL_API_ENTRY cl_int CL_API_CALL clEnqueueReadBuffer(cl_command_queue command_queue ,
|
|
cl_mem buffer ,
|
|
cl_bool /* blocking_read */,
|
|
size_t offset ,
|
|
size_t cb ,
|
|
void * ptr ,
|
|
cl_uint /* num_events_in_wait_list */,
|
|
const cl_event * /* event_wait_list */,
|
|
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
|
|
|
|
///wait for all work items to be completed
|
|
scheduler->flush();
|
|
|
|
memcpy(ptr,(char*)buffer + offset,cb);
|
|
return 0;
|
|
}
|
|
|
|
|
|
CL_API_ENTRY cl_int clGetProgramBuildInfo(cl_program /* program */,
|
|
cl_device_id /* device */,
|
|
cl_program_build_info /* param_name */,
|
|
size_t /* param_value_size */,
|
|
void * /* param_value */,
|
|
size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// Program Object APIs
|
|
CL_API_ENTRY cl_program
|
|
clCreateProgramWithSource(cl_context context ,
|
|
cl_uint /* count */,
|
|
const char ** /* strings */,
|
|
const size_t * /* lengths */,
|
|
cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
*errcode_ret = CL_SUCCESS;
|
|
return (cl_program)context;
|
|
}
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue command_queue ,
|
|
cl_mem buffer ,
|
|
cl_bool /* blocking_read */,
|
|
size_t offset,
|
|
size_t cb ,
|
|
const void * ptr ,
|
|
cl_uint /* num_events_in_wait_list */,
|
|
const cl_event * /* event_wait_list */,
|
|
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
|
|
|
|
///wait for all work items to be completed
|
|
scheduler->flush();
|
|
|
|
memcpy((char*)buffer + offset, ptr,cb);
|
|
return 0;
|
|
}
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clFlush(cl_command_queue command_queue)
|
|
{
|
|
MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
|
|
///wait for all work items to be completed
|
|
scheduler->flush();
|
|
return 0;
|
|
}
|
|
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clEnqueueNDRangeKernel(cl_command_queue /* command_queue */,
|
|
cl_kernel clKernel ,
|
|
cl_uint work_dim ,
|
|
const size_t * /* global_work_offset */,
|
|
const size_t * global_work_size ,
|
|
const size_t * /* local_work_size */,
|
|
cl_uint /* num_events_in_wait_list */,
|
|
const cl_event * /* event_wait_list */,
|
|
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
|
|
|
|
MiniCLKernel* kernel = (MiniCLKernel*) clKernel;
|
|
for (unsigned int ii=0;ii<work_dim;ii++)
|
|
{
|
|
int maxTask = kernel->m_scheduler->getMaxNumOutstandingTasks();
|
|
int numWorkItems = global_work_size[ii];
|
|
|
|
// //at minimum 64 work items per task
|
|
// int numWorkItemsPerTask = btMax(64,numWorkItems / maxTask);
|
|
int numWorkItemsPerTask = numWorkItems / maxTask;
|
|
if (!numWorkItemsPerTask) numWorkItemsPerTask = 1;
|
|
|
|
for (int t=0;t<numWorkItems;)
|
|
{
|
|
//Performance Hint: tweak this number during benchmarking
|
|
int endIndex = (t+numWorkItemsPerTask) < numWorkItems ? t+numWorkItemsPerTask : numWorkItems;
|
|
kernel->m_scheduler->issueTask(t, endIndex, kernel);
|
|
t = endIndex;
|
|
}
|
|
}
|
|
/*
|
|
|
|
void* bla = 0;
|
|
|
|
scheduler->issueTask(bla,2,3);
|
|
scheduler->flush();
|
|
|
|
*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define LOCAL_BUF_SIZE 32768
|
|
static int sLocalMemBuf[LOCAL_BUF_SIZE * 4 + 16];
|
|
static int* spLocalBufCurr = NULL;
|
|
static int sLocalBufUsed = LOCAL_BUF_SIZE; // so it will be reset at the first call
|
|
static void* localBufMalloc(int size)
|
|
{
|
|
int size16 = (size + 15) >> 4; // in 16-byte units
|
|
if((sLocalBufUsed + size16) > LOCAL_BUF_SIZE)
|
|
{ // reset
|
|
spLocalBufCurr = sLocalMemBuf;
|
|
while((size_t)spLocalBufCurr & 0x0F) spLocalBufCurr++; // align to 16 bytes
|
|
sLocalBufUsed = 0;
|
|
}
|
|
void* ret = spLocalBufCurr;
|
|
spLocalBufCurr += size16 * 4;
|
|
sLocalBufUsed += size;
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clSetKernelArg(cl_kernel clKernel ,
|
|
cl_uint arg_index ,
|
|
size_t arg_size ,
|
|
const void * arg_value ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
MiniCLKernel* kernel = (MiniCLKernel* ) clKernel;
|
|
btAssert(arg_size <= MINICL_MAX_ARGLENGTH);
|
|
if (arg_index>MINI_CL_MAX_ARG)
|
|
{
|
|
printf("error: clSetKernelArg arg_index (%u) exceeds %u\n",arg_index,MINI_CL_MAX_ARG);
|
|
} else
|
|
{
|
|
if (arg_size>MINICL_MAX_ARGLENGTH)
|
|
//if (arg_size != MINICL_MAX_ARGLENGTH)
|
|
{
|
|
printf("error: clSetKernelArg argdata too large: %zu (maximum is %zu)\n",arg_size,MINICL_MAX_ARGLENGTH);
|
|
}
|
|
else
|
|
{
|
|
if(arg_value == NULL)
|
|
{ // this is only for __local memory qualifier
|
|
void* ptr = localBufMalloc(arg_size);
|
|
kernel->m_argData[arg_index] = ptr;
|
|
}
|
|
else
|
|
{
|
|
memcpy(&(kernel->m_argData[arg_index]), arg_value, arg_size);
|
|
}
|
|
kernel->m_argSizes[arg_index] = arg_size;
|
|
if(arg_index >= kernel->m_numArgs)
|
|
{
|
|
kernel->m_numArgs = arg_index + 1;
|
|
kernel->updateLauncher();
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Kernel Object APIs
|
|
CL_API_ENTRY cl_kernel CL_API_CALL clCreateKernel(cl_program program ,
|
|
const char * kernel_name ,
|
|
cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) program;
|
|
int nameLen = strlen(kernel_name);
|
|
if(nameLen >= MINI_CL_MAX_KERNEL_NAME)
|
|
{
|
|
*errcode_ret = CL_INVALID_KERNEL_NAME;
|
|
return NULL;
|
|
}
|
|
|
|
MiniCLKernel* kernel = new MiniCLKernel();
|
|
|
|
strcpy(kernel->m_name, kernel_name);
|
|
kernel->m_numArgs = 0;
|
|
|
|
//kernel->m_kernelProgramCommandId = scheduler->findProgramCommandIdByName(kernel_name);
|
|
//if (kernel->m_kernelProgramCommandId>=0)
|
|
//{
|
|
// *errcode_ret = CL_SUCCESS;
|
|
//} else
|
|
//{
|
|
// *errcode_ret = CL_INVALID_KERNEL_NAME;
|
|
//}
|
|
kernel->m_scheduler = scheduler;
|
|
if(kernel->registerSelf() == NULL)
|
|
{
|
|
*errcode_ret = CL_INVALID_KERNEL_NAME;
|
|
delete kernel;
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
*errcode_ret = CL_SUCCESS;
|
|
}
|
|
|
|
return (cl_kernel)kernel;
|
|
|
|
}
|
|
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clBuildProgram(cl_program /* program */,
|
|
cl_uint /* num_devices */,
|
|
const cl_device_id * /* device_list */,
|
|
const char * /* options */,
|
|
void (*pfn_notify)(cl_program /* program */, void * /* user_data */),
|
|
void * /* user_data */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
return CL_SUCCESS;
|
|
}
|
|
|
|
CL_API_ENTRY cl_program CL_API_CALL clCreateProgramWithBinary(cl_context context ,
|
|
cl_uint /* num_devices */,
|
|
const cl_device_id * /* device_list */,
|
|
const size_t * /* lengths */,
|
|
const unsigned char ** /* binaries */,
|
|
cl_int * /* binary_status */,
|
|
cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
return (cl_program)context;
|
|
}
|
|
|
|
|
|
// Memory Object APIs
|
|
CL_API_ENTRY cl_mem CL_API_CALL clCreateBuffer(cl_context /* context */,
|
|
cl_mem_flags flags ,
|
|
size_t size,
|
|
void * host_ptr ,
|
|
cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
cl_mem buf = (cl_mem)malloc(size);
|
|
if ((flags&CL_MEM_COPY_HOST_PTR) && host_ptr)
|
|
{
|
|
memcpy(buf,host_ptr,size);
|
|
}
|
|
*errcode_ret = 0;
|
|
return buf;
|
|
}
|
|
|
|
// Command Queue APIs
|
|
CL_API_ENTRY cl_command_queue CL_API_CALL clCreateCommandQueue(cl_context context ,
|
|
cl_device_id /* device */,
|
|
cl_command_queue_properties /* properties */,
|
|
cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
*errcode_ret = 0;
|
|
return (cl_command_queue) context;
|
|
}
|
|
|
|
extern CL_API_ENTRY cl_int CL_API_CALL clGetContextInfo(cl_context /* context */,
|
|
cl_context_info param_name ,
|
|
size_t param_value_size ,
|
|
void * param_value,
|
|
size_t * param_value_size_ret ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
|
|
switch (param_name)
|
|
{
|
|
case CL_CONTEXT_DEVICES:
|
|
{
|
|
if (!param_value_size)
|
|
{
|
|
*param_value_size_ret = 13;
|
|
} else
|
|
{
|
|
const char* testName = "MiniCL_Test.";
|
|
sprintf((char*)param_value,"%s",testName);
|
|
}
|
|
break;
|
|
};
|
|
default:
|
|
{
|
|
printf("unsupported\n");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
CL_API_ENTRY cl_context CL_API_CALL clCreateContextFromType(const cl_context_properties * /* properties */,
|
|
cl_device_type device_type ,
|
|
void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */,
|
|
void * /* user_data */,
|
|
cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
int maxNumOutstandingTasks = 4;
|
|
// int maxNumOutstandingTasks = 2;
|
|
// int maxNumOutstandingTasks = 1;
|
|
gMiniCLNumOutstandingTasks = maxNumOutstandingTasks;
|
|
const int maxNumOfThreadSupports = 8;
|
|
static int sUniqueThreadSupportIndex = 0;
|
|
static const char* sUniqueThreadSupportName[maxNumOfThreadSupports] =
|
|
{
|
|
"MiniCL_0", "MiniCL_1", "MiniCL_2", "MiniCL_3", "MiniCL_4", "MiniCL_5", "MiniCL_6", "MiniCL_7"
|
|
};
|
|
|
|
btThreadSupportInterface* threadSupport = 0;
|
|
|
|
if (device_type==CL_DEVICE_TYPE_DEBUG)
|
|
{
|
|
SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory);
|
|
threadSupport = new SequentialThreadSupport(stc);
|
|
} else
|
|
{
|
|
|
|
#if _WIN32
|
|
btAssert(sUniqueThreadSupportIndex < maxNumOfThreadSupports);
|
|
const char* bla = "MiniCL";
|
|
threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
|
|
// bla,
|
|
sUniqueThreadSupportName[sUniqueThreadSupportIndex++],
|
|
processMiniCLTask, //processCollisionTask,
|
|
createMiniCLLocalStoreMemory,//createCollisionLocalStoreMemory,
|
|
maxNumOutstandingTasks));
|
|
#else
|
|
|
|
#ifdef USE_PTHREADS
|
|
PosixThreadSupport::ThreadConstructionInfo constructionInfo("PosixThreads",
|
|
processMiniCLTask,
|
|
createMiniCLLocalStoreMemory,
|
|
maxNumOutstandingTasks);
|
|
threadSupport = new PosixThreadSupport(constructionInfo);
|
|
|
|
#else
|
|
///todo: add posix thread support for other platforms
|
|
SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory);
|
|
threadSupport = new SequentialThreadSupport(stc);
|
|
#endif //USE_PTHREADS
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
MiniCLTaskScheduler* scheduler = new MiniCLTaskScheduler(threadSupport,maxNumOutstandingTasks);
|
|
|
|
*errcode_ret = 0;
|
|
return (cl_context)scheduler;
|
|
}
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL
|
|
clGetDeviceIDs(cl_platform_id /* platform */,
|
|
cl_device_type /* device_type */,
|
|
cl_uint /* num_entries */,
|
|
cl_device_id * /* devices */,
|
|
cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
CL_API_ENTRY cl_context CL_API_CALL
|
|
clCreateContext(const cl_context_properties * properties ,
|
|
cl_uint num_devices ,
|
|
const cl_device_id * devices ,
|
|
void (*pfn_notify)(const char *, const void *, size_t, void *),
|
|
void * user_data ,
|
|
cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
|
|
return clCreateContextFromType(properties,CL_DEVICE_TYPE_ALL,pfn_notify,user_data,errcode_ret);
|
|
}
|
|
|
|
CL_API_ENTRY cl_int CL_API_CALL clReleaseContext(cl_context context ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
|
|
MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) context;
|
|
|
|
btThreadSupportInterface* threadSupport = scheduler->getThreadSupportInterface();
|
|
delete scheduler;
|
|
delete threadSupport;
|
|
|
|
return 0;
|
|
}
|
|
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
clFinish(cl_command_queue command_queue ) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
|
|
///wait for all work items to be completed
|
|
scheduler->flush();
|
|
return CL_SUCCESS;
|
|
}
|
|
|
|
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
clGetProgramInfo(cl_program /* program */,
|
|
cl_program_info /* param_name */,
|
|
size_t /* param_value_size */,
|
|
void * /* param_value */,
|
|
size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
clGetKernelWorkGroupInfo(cl_kernel kernel ,
|
|
cl_device_id /* device */,
|
|
cl_kernel_work_group_info wgi/* param_name */,
|
|
size_t sz /* param_value_size */,
|
|
void * ptr /* param_value */,
|
|
size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0
|
|
{
|
|
if((wgi == CL_KERNEL_WORK_GROUP_SIZE)
|
|
&&(sz == sizeof(size_t))
|
|
&&(ptr != NULL))
|
|
{
|
|
MiniCLKernel* miniCLKernel = (MiniCLKernel*)kernel;
|
|
MiniCLTaskScheduler* scheduler = miniCLKernel->m_scheduler;
|
|
*((size_t*)ptr) = scheduler->getMaxNumOutstandingTasks();
|
|
return CL_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
return CL_INVALID_VALUE;
|
|
}
|
|
}
|