Apply a patch that updates vertex position on GPU for the OpenCL version, by Dongsoo Han (saggita), work-in-progress
Removed the unused OpenCL kernels Add example how to cache binary kernels, see SoftDemo compiled with OpenCL AMD using msvc/vs2008_opencl.bat
This commit is contained in:
@@ -22,6 +22,12 @@ subject to the following restrictions:
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define btAssert assert
|
||||||
|
#endif
|
||||||
|
|
||||||
//Set the preferred platform vendor using the OpenCL SDK
|
//Set the preferred platform vendor using the OpenCL SDK
|
||||||
static char* spPlatformVendor =
|
static char* spPlatformVendor =
|
||||||
@@ -65,9 +71,8 @@ cl_platform_id btOpenCLUtils::getPlatform(int platformIndex, cl_int* pErrNum)
|
|||||||
{
|
{
|
||||||
cl_platform_id platform = 0;
|
cl_platform_id platform = 0;
|
||||||
|
|
||||||
cl_uint clNumPlatforms;
|
cl_uint numPlatforms;
|
||||||
cl_int ciErrNum = clGetPlatformIDs(0, NULL, &clNumPlatforms);
|
cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
|
||||||
int numPlatforms = (int)clNumPlatforms;
|
|
||||||
|
|
||||||
if (platformIndex>=0 && platformIndex<numPlatforms)
|
if (platformIndex>=0 && platformIndex<numPlatforms)
|
||||||
{
|
{
|
||||||
@@ -112,8 +117,7 @@ cl_context btOpenCLUtils::createContextFromPlatform(cl_platform_id platform, cl_
|
|||||||
cl_context_properties cps[7] = {0,0,0,0,0,0,0};
|
cl_context_properties cps[7] = {0,0,0,0,0,0,0};
|
||||||
cps[0] = CL_CONTEXT_PLATFORM;
|
cps[0] = CL_CONTEXT_PLATFORM;
|
||||||
cps[1] = (cl_context_properties)platform;
|
cps[1] = (cl_context_properties)platform;
|
||||||
#if defined( _WIN32) && !defined(CL_PLATFORM_MINI_CL)
|
#if defined (_WIN32) && defined(_MSC_VER) && !defined (CL_PLATFORM_MINI_CL)
|
||||||
//#if !defined (CL_PLATFORM_MINI_CL) && !defined (__APPLE__)
|
|
||||||
if (pGLContext && pGLDC)
|
if (pGLContext && pGLDC)
|
||||||
{
|
{
|
||||||
cps[2] = CL_GL_CONTEXT_KHR;
|
cps[2] = CL_GL_CONTEXT_KHR;
|
||||||
@@ -139,13 +143,10 @@ cl_context btOpenCLUtils::createContextFromPlatform(cl_platform_id platform, cl_
|
|||||||
|
|
||||||
cl_context btOpenCLUtils::createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC )
|
cl_context btOpenCLUtils::createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC )
|
||||||
{
|
{
|
||||||
cl_uint clNumPlatforms;
|
cl_uint numPlatforms;
|
||||||
cl_context retContext = 0;
|
cl_context retContext = 0;
|
||||||
|
|
||||||
cl_int ciErrNum = clGetPlatformIDs(0, NULL, &clNumPlatforms);
|
cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
|
||||||
int numPlatforms = (int)clNumPlatforms;
|
|
||||||
|
|
||||||
|
|
||||||
if(ciErrNum != CL_SUCCESS)
|
if(ciErrNum != CL_SUCCESS)
|
||||||
{
|
{
|
||||||
if(pErrNum != NULL) *pErrNum = ciErrNum;
|
if(pErrNum != NULL) *pErrNum = ciErrNum;
|
||||||
@@ -228,11 +229,10 @@ cl_device_id btOpenCLUtils::getDevice(cl_context cxMainContext, int deviceIndex)
|
|||||||
// get the list of devices associated with context
|
// get the list of devices associated with context
|
||||||
clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes);
|
clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes);
|
||||||
|
|
||||||
if( int(szParmDataBytes / sizeof(cl_device_id)) < deviceIndex ) {
|
if( szParmDataBytes / sizeof(cl_device_id) < deviceIndex ) {
|
||||||
return (cl_device_id)-1;
|
return (cl_device_id)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cdDevices = (cl_device_id*) malloc(szParmDataBytes);
|
cdDevices = (cl_device_id*) malloc(szParmDataBytes);
|
||||||
|
|
||||||
clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL);
|
clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL);
|
||||||
@@ -389,43 +389,214 @@ void btOpenCLUtils::getDeviceInfo(cl_device_id device, btOpenCLDeviceInfo& info)
|
|||||||
clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), &info.m_vecWidthDouble, NULL);
|
clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), &info.m_vecWidthDouble, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* strip2(const char* name, const char* pattern)
|
||||||
cl_kernel btOpenCLUtils::compileCLKernelFromString(cl_context clContext, const char* kernelSource, const char* kernelName, const char* additionalMacros )
|
|
||||||
{
|
{
|
||||||
printf("compiling kernelName: %s ",kernelName);
|
size_t const patlen = strlen(pattern);
|
||||||
cl_kernel kernel;
|
size_t patcnt = 0;
|
||||||
cl_int ciErrNum;
|
const char * oriptr;
|
||||||
|
const char * patloc;
|
||||||
|
// find how many times the pattern occurs in the original string
|
||||||
|
for (oriptr = name; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
|
||||||
|
{
|
||||||
|
patcnt++;
|
||||||
|
}
|
||||||
|
return oriptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_program btOpenCLUtils::compileCLProgramFromString(cl_context clContext, cl_device_id device, const char* kernelSource, cl_int* pErrNum, const char* additionalMacros , const char* clFileNameForCaching)
|
||||||
|
{
|
||||||
|
|
||||||
|
cl_program m_cpProgram=0;
|
||||||
|
cl_int status;
|
||||||
|
|
||||||
|
char binaryFileName[522];
|
||||||
|
|
||||||
|
if (clFileNameForCaching)
|
||||||
|
{
|
||||||
|
|
||||||
|
char deviceName[256];
|
||||||
|
char driverVersion[256];
|
||||||
|
clGetDeviceInfo(device, CL_DEVICE_NAME, 256, &deviceName, NULL);
|
||||||
|
clGetDeviceInfo(device, CL_DRIVER_VERSION, 256, &driverVersion, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
const char* strippedName = strip2(clFileNameForCaching,"\\");
|
||||||
|
strippedName = strip2(strippedName,"/");
|
||||||
|
|
||||||
|
sprintf_s(binaryFileName,"%s.%s.%s.bin",strippedName, deviceName,driverVersion );
|
||||||
|
//printf("searching for %s\n", binaryFileName);
|
||||||
|
|
||||||
|
bool fileUpToDate = false;
|
||||||
|
bool binaryFileValid=false;
|
||||||
|
|
||||||
|
FILETIME modtimeBinary;
|
||||||
|
|
||||||
|
#if defined (_WIN32) && defined(_MSC_VER)
|
||||||
|
{
|
||||||
|
|
||||||
|
HANDLE binaryFileHandle = CreateFile(binaryFileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
|
||||||
|
if (binaryFileHandle ==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD errorCode;
|
||||||
|
errorCode = GetLastError();
|
||||||
|
switch (errorCode)
|
||||||
|
{
|
||||||
|
case ERROR_FILE_NOT_FOUND:
|
||||||
|
{
|
||||||
|
printf("\nCached file not found %s\n", binaryFileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR_PATH_NOT_FOUND:
|
||||||
|
{
|
||||||
|
printf("\nCached file path not found %s\n", binaryFileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
printf("\nFailed reading cached file with errorCode = %d\n", errorCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (GetFileTime(binaryFileHandle, NULL, NULL, &modtimeBinary)==0)
|
||||||
|
{
|
||||||
|
DWORD errorCode;
|
||||||
|
errorCode = GetLastError();
|
||||||
|
printf("\nGetFileTime errorCode = %d\n", errorCode);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
binaryFileValid = true;
|
||||||
|
}
|
||||||
|
CloseHandle(binaryFileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryFileValid)
|
||||||
|
{
|
||||||
|
HANDLE srcFileHandle = CreateFile(clFileNameForCaching,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
|
||||||
|
if (srcFileHandle!=INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
FILETIME modtimeSrc;
|
||||||
|
if (GetFileTime(srcFileHandle, NULL, NULL, &modtimeSrc)==0)
|
||||||
|
{
|
||||||
|
DWORD errorCode;
|
||||||
|
errorCode = GetLastError();
|
||||||
|
printf("\nGetFileTime errorCode = %d\n", errorCode);
|
||||||
|
}
|
||||||
|
if ( ( modtimeSrc.dwHighDateTime < modtimeBinary.dwHighDateTime)
|
||||||
|
||(( modtimeSrc.dwHighDateTime == modtimeBinary.dwHighDateTime)&&(modtimeSrc.dwLowDateTime <= modtimeBinary.dwLowDateTime)))
|
||||||
|
{
|
||||||
|
fileUpToDate=true;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
printf("\nCached binary file out-of-date (%s)\n",binaryFileName);
|
||||||
|
}
|
||||||
|
CloseHandle(srcFileHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
DWORD errorCode;
|
||||||
|
errorCode = GetLastError();
|
||||||
|
switch (errorCode)
|
||||||
|
{
|
||||||
|
case ERROR_FILE_NOT_FOUND:
|
||||||
|
{
|
||||||
|
printf("\nSrc file not found %s\n", clFileNameForCaching);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR_PATH_NOT_FOUND:
|
||||||
|
{
|
||||||
|
printf("\nSrc path not found %s\n", clFileNameForCaching);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
printf("\nnSrc file reading errorCode = %d\n", errorCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//we should make sure the src file exists so we can verify the timestamp with binary
|
||||||
|
assert(0);
|
||||||
|
#else
|
||||||
|
//if we cannot find the source, assume it is OK in release builds
|
||||||
|
fileUpToDate = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fileUpToDate)
|
||||||
|
{
|
||||||
|
FILE* file = fopen(binaryFileName, "rb");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
fseek( file, 0L, SEEK_END );
|
||||||
|
size_t binarySize = ftell( file );
|
||||||
|
rewind( file );
|
||||||
|
char* binary = new char[binarySize];
|
||||||
|
fread( binary, sizeof(char), binarySize, file );
|
||||||
|
fclose( file );
|
||||||
|
|
||||||
|
m_cpProgram = clCreateProgramWithBinary( clContext, 1,&device, &binarySize, (const unsigned char**)&binary, 0, &status );
|
||||||
|
btAssert( status == CL_SUCCESS );
|
||||||
|
status = clBuildProgram( m_cpProgram, 1, &device, additionalMacros, 0, 0 );
|
||||||
|
btAssert( status == CL_SUCCESS );
|
||||||
|
|
||||||
|
if( status != CL_SUCCESS )
|
||||||
|
{
|
||||||
|
char *build_log;
|
||||||
|
size_t ret_val_size;
|
||||||
|
clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
|
||||||
|
build_log = new char[ret_val_size+1];
|
||||||
|
clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
|
||||||
|
build_log[ret_val_size] = '\0';
|
||||||
|
printf("%s\n", build_log);
|
||||||
|
delete build_log;
|
||||||
|
btAssert(0);
|
||||||
|
m_cpProgram = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //_WIN32
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_cpProgram)
|
||||||
|
{
|
||||||
|
// cl_kernel kernel;
|
||||||
|
cl_int localErrNum;
|
||||||
size_t program_length = strlen(kernelSource);
|
size_t program_length = strlen(kernelSource);
|
||||||
|
|
||||||
cl_program m_cpProgram = clCreateProgramWithSource(clContext, 1, (const char**)&kernelSource, &program_length, &ciErrNum);
|
m_cpProgram = clCreateProgramWithSource(clContext, 1, (const char**)&kernelSource, &program_length, &localErrNum);
|
||||||
// oclCHECKERROR(ciErrNum, CL_SUCCESS);
|
if (localErrNum!= CL_SUCCESS)
|
||||||
|
{
|
||||||
|
if (pErrNum)
|
||||||
|
*pErrNum = localErrNum;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Build the program with 'mad' Optimization option
|
// Build the program with 'mad' Optimization option
|
||||||
|
|
||||||
|
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
char* flags = "-cl-mad-enable -DMAC -DGUID_ARG";
|
char* flags = "-cl-mad-enable -DMAC -DGUID_ARG";
|
||||||
#else
|
#else
|
||||||
//const char* flags = "-DGUID_ARG= -fno-alias";
|
//const char* flags = "-DGUID_ARG= -fno-alias";
|
||||||
const char* flags = "-DGUID_ARG= ";
|
const char* flags = "-DGUID_ARG= ";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char* compileFlags = new char[strlen(additionalMacros) + strlen(flags) + 5];
|
char* compileFlags = new char[strlen(additionalMacros) + strlen(flags) + 5];
|
||||||
sprintf(compileFlags, "%s %s", flags, additionalMacros);
|
sprintf(compileFlags, "%s %s", flags, additionalMacros);
|
||||||
ciErrNum = clBuildProgram(m_cpProgram, 0, NULL, compileFlags, NULL, NULL);
|
localErrNum = clBuildProgram(m_cpProgram, 1, &device, compileFlags, NULL, NULL);
|
||||||
if (ciErrNum != CL_SUCCESS)
|
if (localErrNum!= CL_SUCCESS)
|
||||||
{
|
|
||||||
size_t numDevices;
|
|
||||||
clGetProgramInfo( m_cpProgram, CL_PROGRAM_DEVICES, 0, 0, &numDevices );
|
|
||||||
cl_device_id *devices = new cl_device_id[numDevices];
|
|
||||||
clGetProgramInfo( m_cpProgram, CL_PROGRAM_DEVICES, numDevices, devices, &numDevices );
|
|
||||||
for( int i = 0; i < 2; ++i )
|
|
||||||
{
|
{
|
||||||
char *build_log;
|
char *build_log;
|
||||||
size_t ret_val_size;
|
size_t ret_val_size;
|
||||||
clGetProgramBuildInfo(m_cpProgram, devices[i], CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
|
clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
|
||||||
build_log = new char[ret_val_size+1];
|
build_log = new char[ret_val_size+1];
|
||||||
clGetProgramBuildInfo(m_cpProgram, devices[i], CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
|
clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
|
||||||
|
|
||||||
// to be carefully, terminate with \0
|
// to be carefully, terminate with \0
|
||||||
// there's no information in the reference whether the string is 0 terminated or not
|
// there's no information in the reference whether the string is 0 terminated or not
|
||||||
@@ -434,24 +605,80 @@ cl_kernel btOpenCLUtils::compileCLKernelFromString(cl_context clContext, const c
|
|||||||
|
|
||||||
printf("Error in clBuildProgram, Line %u in file %s, Log: \n%s\n !!!\n\n", __LINE__, __FILE__, build_log);
|
printf("Error in clBuildProgram, Line %u in file %s, Log: \n%s\n !!!\n\n", __LINE__, __FILE__, build_log);
|
||||||
delete[] build_log;
|
delete[] build_log;
|
||||||
|
if (pErrNum)
|
||||||
|
*pErrNum = localErrNum;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
assert(0);
|
|
||||||
exit(0);
|
#if defined (_WIN32) && defined(_MSC_VER)
|
||||||
|
if( clFileNameForCaching )
|
||||||
|
{ // write to binary
|
||||||
|
size_t binarySize;
|
||||||
|
status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binarySize, 0 );
|
||||||
|
btAssert( status == CL_SUCCESS );
|
||||||
|
|
||||||
|
char* binary = new char[binarySize];
|
||||||
|
|
||||||
|
status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARIES, sizeof(char*), &binary, 0 );
|
||||||
|
btAssert( status == CL_SUCCESS );
|
||||||
|
|
||||||
|
{
|
||||||
|
FILE* file = fopen(binaryFileName, "wb");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
fwrite( binary, sizeof(char), binarySize, file );
|
||||||
|
fclose( file );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
printf("cannot write file %s\n", binaryFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] binary;
|
||||||
|
}
|
||||||
|
#endif//defined (_WIN32) && defined(_MSC_VER)
|
||||||
|
|
||||||
|
delete [] compileFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_cpProgram;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
printf("compiling kernel %s ",kernelName);
|
||||||
|
cl_kernel kernel;
|
||||||
|
cl_int localErrNum;
|
||||||
|
size_t program_length = strlen(kernelSource);
|
||||||
|
|
||||||
|
|
||||||
|
cl_program m_cpProgram = prog;
|
||||||
|
if (!m_cpProgram)
|
||||||
|
{
|
||||||
|
m_cpProgram = compileCLProgramFromString(clContext,device,kernelSource,pErrNum, additionalMacros);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create the kernel
|
// Create the kernel
|
||||||
kernel = clCreateKernel(m_cpProgram, kernelName, &ciErrNum);
|
kernel = clCreateKernel(m_cpProgram, kernelName, &localErrNum);
|
||||||
if (ciErrNum != CL_SUCCESS)
|
if (localErrNum != CL_SUCCESS)
|
||||||
{
|
{
|
||||||
printf("Error in clCreateKernel, Line %u in file %s !!!\n\n", __LINE__, __FILE__);
|
printf("Error in clCreateKernel, Line %u in file %s, cannot find kernel function %s !!!\n\n", __LINE__, __FILE__, kernelName);
|
||||||
assert(0);
|
if (pErrNum)
|
||||||
exit(0);
|
*pErrNum = localErrNum;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!prog && m_cpProgram)
|
||||||
|
{
|
||||||
clReleaseProgram(m_cpProgram);
|
clReleaseProgram(m_cpProgram);
|
||||||
|
}
|
||||||
printf("ready. \n");
|
printf("ready. \n");
|
||||||
delete [] compileFlags;
|
|
||||||
|
|
||||||
|
if (pErrNum)
|
||||||
|
*pErrNum = CL_SUCCESS;
|
||||||
return kernel;
|
return kernel;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,10 @@ public:
|
|||||||
static void getDeviceInfo(cl_device_id device, btOpenCLDeviceInfo& info);
|
static void getDeviceInfo(cl_device_id device, btOpenCLDeviceInfo& info);
|
||||||
static void printDeviceInfo(cl_device_id device);
|
static void printDeviceInfo(cl_device_id device);
|
||||||
|
|
||||||
static cl_kernel compileCLKernelFromString( cl_context clContext,const char* kernelSource, const char* kernelName, const char* additionalMacros = "" );
|
static cl_kernel compileCLKernelFromString( cl_context clContext,cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum=0, cl_program prog=0,const char* additionalMacros = "" );
|
||||||
|
|
||||||
|
//optional
|
||||||
|
static cl_program compileCLProgramFromString( cl_context clContext,cl_device_id device, const char* kernelSource, cl_int* pErrNum=0,const char* additionalMacros = "" , const char* srcFileNameForCaching=0);
|
||||||
|
|
||||||
//the following optional APIs provide access using specific platform information
|
//the following optional APIs provide access using specific platform information
|
||||||
static int getNumPlatforms(cl_int* pErrNum=0);
|
static int getNumPlatforms(cl_int* pErrNum=0);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ static btRigidBody* staticBody = 0;
|
|||||||
static float waveheight = 5.f;
|
static float waveheight = 5.f;
|
||||||
|
|
||||||
const float TRIANGLE_SIZE=8.f;
|
const float TRIANGLE_SIZE=8.f;
|
||||||
unsigned int current_demo=29;
|
unsigned int current_demo=7;
|
||||||
#define DEMO_MODE_TIMEOUT 15.f //15 seconds for each demo
|
#define DEMO_MODE_TIMEOUT 15.f //15 seconds for each demo
|
||||||
|
|
||||||
|
|
||||||
@@ -67,6 +67,151 @@ const int maxNumObjects = 32760;
|
|||||||
#define CUBE_HALF_EXTENTS 1.5
|
#define CUBE_HALF_EXTENTS 1.5
|
||||||
#define EXTRA_HEIGHT -10.f
|
#define EXTRA_HEIGHT -10.f
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_AMD_OPENCL
|
||||||
|
#include "btOpenCLUtils.h"
|
||||||
|
#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h"
|
||||||
|
#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h"
|
||||||
|
#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexBuffer_OpenGL.h"
|
||||||
|
|
||||||
|
btOpenCLSoftBodySolver* g_openCLSIMDSolver=0;
|
||||||
|
btSoftBodySolverOutputCLtoCPU* g_softBodyOutput = 0;
|
||||||
|
|
||||||
|
cl_context g_cxMainContext;
|
||||||
|
cl_device_id g_cdDevice;
|
||||||
|
cl_command_queue g_cqCommandQue;
|
||||||
|
|
||||||
|
void initCL( void* glCtx, void* glDC )
|
||||||
|
{
|
||||||
|
int ciErrNum = 0;
|
||||||
|
|
||||||
|
#if defined(CL_PLATFORM_MINI_CL)
|
||||||
|
cl_device_type deviceType = CL_DEVICE_TYPE_CPU;//or use CL_DEVICE_TYPE_DEBUG to debug MiniCL
|
||||||
|
#elif defined(CL_PLATFORM_INTEL)
|
||||||
|
cl_device_type deviceType = CL_DEVICE_TYPE_CPU;
|
||||||
|
#elif defined(CL_PLATFORM_AMD)
|
||||||
|
cl_device_type deviceType = CL_DEVICE_TYPE_GPU;
|
||||||
|
#elif defined(CL_PLATFORM_NVIDIA)
|
||||||
|
cl_device_type deviceType = CL_DEVICE_TYPE_GPU;
|
||||||
|
#else
|
||||||
|
#ifdef __APPLE__
|
||||||
|
cl_device_type deviceType = CL_DEVICE_TYPE_ALL;//GPU;
|
||||||
|
#else
|
||||||
|
cl_device_type deviceType = CL_DEVICE_TYPE_CPU;//CL_DEVICE_TYPE_ALL
|
||||||
|
#endif//__APPLE__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_cxMainContext = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC);
|
||||||
|
oclCHECKERROR(ciErrNum, CL_SUCCESS);
|
||||||
|
|
||||||
|
|
||||||
|
int numDev = btOpenCLUtils::getNumDevices(g_cxMainContext);
|
||||||
|
if (!numDev)
|
||||||
|
{
|
||||||
|
btAssert(0);
|
||||||
|
exit(0);//this is just a demo, exit now
|
||||||
|
}
|
||||||
|
|
||||||
|
g_cdDevice = btOpenCLUtils::getDevice(g_cxMainContext,0);
|
||||||
|
oclCHECKERROR(ciErrNum, CL_SUCCESS);
|
||||||
|
|
||||||
|
btOpenCLDeviceInfo clInfo;
|
||||||
|
btOpenCLUtils::getDeviceInfo(g_cdDevice,clInfo);
|
||||||
|
btOpenCLUtils::printDeviceInfo(g_cdDevice);
|
||||||
|
|
||||||
|
// create a command-queue
|
||||||
|
g_cqCommandQue = clCreateCommandQueue(g_cxMainContext, g_cdDevice, 0, &ciErrNum);
|
||||||
|
oclCHECKERROR(ciErrNum, CL_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CachingCLFunctions : public CLFunctions
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
cl_device_id m_device;
|
||||||
|
|
||||||
|
const char* strip(const char* name, const char* pattern);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CachingCLFunctions(cl_command_queue cqCommandQue, cl_context cxMainContext) :
|
||||||
|
CLFunctions(cqCommandQue,cxMainContext)
|
||||||
|
{
|
||||||
|
size_t actualSize;
|
||||||
|
cl_int retval = clGetCommandQueueInfo ( cqCommandQue, CL_QUEUE_DEVICE, sizeof(cl_device_id),
|
||||||
|
&m_device, &actualSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile a compute shader kernel from a string and return the appropriate cl_kernel object.
|
||||||
|
*/
|
||||||
|
virtual cl_kernel compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros , const char* orgSrcFileNameForCaching)
|
||||||
|
{
|
||||||
|
char srcFileNameForCaching[1024];
|
||||||
|
sprintf(srcFileNameForCaching,"%s/%s","../../src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL",orgSrcFileNameForCaching);
|
||||||
|
|
||||||
|
btAssert(additionalMacros);
|
||||||
|
btAssert(srcFileNameForCaching && strlen(srcFileNameForCaching));
|
||||||
|
|
||||||
|
printf("compiling kernelName: %s ",kernelName);
|
||||||
|
cl_kernel kernel=0;
|
||||||
|
cl_int ciErrNum;
|
||||||
|
|
||||||
|
|
||||||
|
size_t program_length = strlen(kernelSource);
|
||||||
|
|
||||||
|
cl_program m_cpProgram = btOpenCLUtils::compileCLProgramFromString(m_cxMainContext, m_device, kernelSource, &ciErrNum, additionalMacros,srcFileNameForCaching);
|
||||||
|
|
||||||
|
|
||||||
|
// Create the kernel
|
||||||
|
kernel = clCreateKernel(m_cpProgram, kernelName, &ciErrNum);
|
||||||
|
if (ciErrNum != CL_SUCCESS)
|
||||||
|
{
|
||||||
|
const char* msg = "";
|
||||||
|
switch(ciErrNum)
|
||||||
|
{
|
||||||
|
case CL_INVALID_PROGRAM:
|
||||||
|
msg = "Program is not a valid program object.";
|
||||||
|
break;
|
||||||
|
case CL_INVALID_PROGRAM_EXECUTABLE:
|
||||||
|
msg = "There is no successfully built executable for program.";
|
||||||
|
break;
|
||||||
|
case CL_INVALID_KERNEL_NAME:
|
||||||
|
msg = "kernel_name is not found in program.";
|
||||||
|
break;
|
||||||
|
case CL_INVALID_KERNEL_DEFINITION:
|
||||||
|
msg = "the function definition for __kernel function given by kernel_name such as the number of arguments, the argument types are not the same for all devices for which the program executable has been built.";
|
||||||
|
break;
|
||||||
|
case CL_INVALID_VALUE:
|
||||||
|
msg = "kernel_name is NULL.";
|
||||||
|
break;
|
||||||
|
case CL_OUT_OF_HOST_MEMORY:
|
||||||
|
msg = "Failure to allocate resources required by the OpenCL implementation on the host.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Error in clCreateKernel for kernel '%s', error is \"%s\", Line %u in file %s !!!\n\n", kernelName, msg, __LINE__, __FILE__);
|
||||||
|
|
||||||
|
#ifndef BT_SUPPRESS_OPENCL_ASSERTS
|
||||||
|
btAssert(0);
|
||||||
|
#endif //BT_SUPPRESS_OPENCL_ASSERTS
|
||||||
|
m_kernelCompilationFailures++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("ready. \n");
|
||||||
|
if (!kernel)
|
||||||
|
m_kernelCompilationFailures++;
|
||||||
|
return kernel;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //USE_AMD_OPENCL
|
||||||
|
|
||||||
//
|
//
|
||||||
void SoftDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos )
|
void SoftDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos )
|
||||||
{
|
{
|
||||||
@@ -409,6 +554,50 @@ static void Init_Impact(SoftDemo* pdemo)
|
|||||||
pdemo->localCreateRigidBody(10,startTransform,new btBoxShape(btVector3(2,2,2)));
|
pdemo->localCreateRigidBody(10,startTransform,new btBoxShape(btVector3(2,2,2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Init_CapsuleCollision(SoftDemo* pdemo)
|
||||||
|
{
|
||||||
|
#ifdef USE_AMD_OPENCL
|
||||||
|
btAlignedObjectArray<btSoftBody*> emptyArray;
|
||||||
|
if (g_openCLSIMDSolver)
|
||||||
|
g_openCLSIMDSolver->optimize(emptyArray);
|
||||||
|
#endif //USE_AMD_OPENCL
|
||||||
|
|
||||||
|
//TRACEDEMO
|
||||||
|
const btScalar s=4;
|
||||||
|
const btScalar h=6;
|
||||||
|
const int r=20;
|
||||||
|
|
||||||
|
btTransform startTransform;
|
||||||
|
startTransform.setIdentity();
|
||||||
|
startTransform.setOrigin(btVector3(0,h-2,0));
|
||||||
|
|
||||||
|
btCollisionShape* capsuleShape= new btCapsuleShapeX(1,5);
|
||||||
|
// capsuleShape->setMargin( 0.5 );
|
||||||
|
|
||||||
|
// capsule->setLocalScaling(btVector3(5,1,1));
|
||||||
|
// btRigidBody* body=pdemo->localCreateRigidBody(20,startTransform,capsuleShape);
|
||||||
|
btRigidBody* body=pdemo->localCreateRigidBody(0,startTransform,capsuleShape);
|
||||||
|
// body->setFriction( 0.8f );
|
||||||
|
|
||||||
|
int fixed=0;//4+8;
|
||||||
|
btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,btVector3(-s,h,-s),
|
||||||
|
btVector3(+s,h,-s),
|
||||||
|
btVector3(-s,h,+s),
|
||||||
|
btVector3(+s,h,+s),r,r,fixed,true);
|
||||||
|
pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
|
||||||
|
// psb->setTotalMass(1);
|
||||||
|
|
||||||
|
psb->m_cfg.piterations = 10;
|
||||||
|
psb->m_cfg.citerations = 10;
|
||||||
|
psb->m_cfg.diterations = 10;
|
||||||
|
// psb->m_cfg.viterations = 10;
|
||||||
|
|
||||||
|
|
||||||
|
// psb->appendAnchor(0,body);
|
||||||
|
// psb->appendAnchor(r-1,body);
|
||||||
|
// pdemo->m_cutting=true;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Collide
|
// Collide
|
||||||
//
|
//
|
||||||
@@ -1319,6 +1508,7 @@ static void Init_TetraCube(SoftDemo* pdemo)
|
|||||||
Init_RopeAttach,
|
Init_RopeAttach,
|
||||||
Init_ClothAttach,
|
Init_ClothAttach,
|
||||||
Init_Sticks,
|
Init_Sticks,
|
||||||
|
Init_CapsuleCollision,
|
||||||
Init_Collide,
|
Init_Collide,
|
||||||
Init_Collide2,
|
Init_Collide2,
|
||||||
Init_Collide3,
|
Init_Collide3,
|
||||||
@@ -1499,6 +1689,11 @@ void SoftDemo::clientMoveAndDisplay()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_AMD_OPENCL
|
||||||
|
if (g_openCLSIMDSolver)
|
||||||
|
g_openCLSIMDSolver->copyBackToSoftBodies();
|
||||||
|
#endif //USE_AMD_OPENCL
|
||||||
|
|
||||||
if(m_drag)
|
if(m_drag)
|
||||||
{
|
{
|
||||||
m_node->m_v*=0;
|
m_node->m_v*=0;
|
||||||
@@ -1615,6 +1810,8 @@ void SoftDemo::renderme()
|
|||||||
/* Cast rays */
|
/* Cast rays */
|
||||||
{
|
{
|
||||||
m_clock.reset();
|
m_clock.reset();
|
||||||
|
if (sbs.size())
|
||||||
|
{
|
||||||
btVector3* org=&origins[0];
|
btVector3* org=&origins[0];
|
||||||
btScalar* fraction=&fractions[0];
|
btScalar* fraction=&fractions[0];
|
||||||
btSoftBody** psbs=&sbs[0];
|
btSoftBody** psbs=&sbs[0];
|
||||||
@@ -1636,6 +1833,7 @@ void SoftDemo::renderme()
|
|||||||
long rayperseconds=(1000*(origins.size()*sbs.size()))/ms;
|
long rayperseconds=(1000*(origins.size()*sbs.size()))/ms;
|
||||||
printf("%d ms (%d rays/s)\r\n",int(ms),int(rayperseconds));
|
printf("%d ms (%d rays/s)\r\n",int(ms),int(rayperseconds));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Draw rays */
|
/* Draw rays */
|
||||||
const btVector3 c[]={ origins[0],
|
const btVector3 c[]={ origins[0],
|
||||||
origins[res-1],
|
origins[res-1],
|
||||||
@@ -1994,7 +2192,35 @@ void SoftDemo::initPhysics()
|
|||||||
|
|
||||||
m_solver = solver;
|
m_solver = solver;
|
||||||
|
|
||||||
btDiscreteDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
btSoftBodySolver* softBodySolver = 0;
|
||||||
|
#ifdef USE_AMD_OPENCL
|
||||||
|
|
||||||
|
static bool once = true;
|
||||||
|
if (once)
|
||||||
|
{
|
||||||
|
once=false;
|
||||||
|
initCL(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( g_openCLSIMDSolver )
|
||||||
|
delete g_openCLSIMDSolver;
|
||||||
|
if( g_softBodyOutput )
|
||||||
|
delete g_softBodyOutput;
|
||||||
|
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
|
g_openCLSIMDSolver = new btOpenCLSoftBodySolverSIMDAware( g_cqCommandQue, g_cxMainContext);
|
||||||
|
// g_openCLSIMDSolver = new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext);
|
||||||
|
g_openCLSIMDSolver->setCLFunctions(new CachingCLFunctions(g_cqCommandQue, g_cxMainContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
softBodySolver = g_openCLSIMDSolver;
|
||||||
|
g_softBodyOutput = new btSoftBodySolverOutputCLtoCPU;
|
||||||
|
#endif //USE_AMD_OPENCL
|
||||||
|
|
||||||
|
btDiscreteDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration,softBodySolver);
|
||||||
m_dynamicsWorld = world;
|
m_dynamicsWorld = world;
|
||||||
m_dynamicsWorld->setInternalTickCallback(pickingPreTickCallback,this,true);
|
m_dynamicsWorld->setInternalTickCallback(pickingPreTickCallback,this,true);
|
||||||
|
|
||||||
@@ -2003,11 +2229,6 @@ void SoftDemo::initPhysics()
|
|||||||
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
|
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
|
||||||
m_softBodyWorldInfo.m_gravity.setValue(0,-10,0);
|
m_softBodyWorldInfo.m_gravity.setValue(0,-10,0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// clientResetScene();
|
// clientResetScene();
|
||||||
|
|
||||||
m_softBodyWorldInfo.m_sparsesdf.Initialize();
|
m_softBodyWorldInfo.m_sparsesdf.Initialize();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ function createDemos( demos, incdirs, linknames)
|
|||||||
libdirs {"../Glut"}
|
libdirs {"../Glut"}
|
||||||
files { "../msvc/bullet.rc" }
|
files { "../msvc/bullet.rc" }
|
||||||
|
|
||||||
configuration {"MaxOSX"}
|
configuration {"MacOSX"}
|
||||||
--print "hello"
|
--print "hello"
|
||||||
linkoptions { "-framework Carbon -framework OpenGL -framework AGL -framework Glut" }
|
linkoptions { "-framework Carbon -framework OpenGL -framework AGL -framework Glut" }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user