00001 #include "btSoftBodySolverOutputCLtoGL.h"
00002 #include <stdio.h>
00003 #include "btSoftBodySolver_OpenCL.h"
00004 #include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
00005 #include "btSoftBodySolverVertexBuffer_OpenGL.h"
00006 #include "BulletSoftBody/btSoftBody.h"
00007
00009 #define MSTRINGIFY(A) #A
00010 static char* OutputToVertexArrayCLString =
00011 #include "OpenCLC10/OutputToVertexArray.cl"
00012
00013
00014 #define RELEASE_CL_KERNEL(kernelName) {if( kernelName ){ clReleaseKernel( kernelName ); kernelName = 0; }}
00015
00016 static const size_t workGroupSize = 128;
00017
00018 void btSoftBodySolverOutputCLtoGL::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
00019 {
00020
00021 btSoftBodySolver *solver = softBody->getSoftBodySolver();
00022 btAssert( solver->getSolverType() == btSoftBodySolver::CL_SOLVER || solver->getSolverType() == btSoftBodySolver::CL_SIMD_SOLVER );
00023 btOpenCLSoftBodySolver *dxSolver = static_cast< btOpenCLSoftBodySolver * >( solver );
00024 checkInitialized();
00025 btOpenCLAcceleratedSoftBodyInterface* currentCloth = dxSolver->findSoftBodyInterface( softBody );
00026 btSoftBodyVertexDataOpenCL &vertexData( dxSolver->m_vertexData );
00027
00028 const int firstVertex = currentCloth->getFirstVertex();
00029 const int lastVertex = firstVertex + currentCloth->getNumVertices();
00030
00031 if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::OPENGL_BUFFER ) {
00032
00033 const btOpenGLInteropVertexBufferDescriptor *openGLVertexBuffer = static_cast< btOpenGLInteropVertexBufferDescriptor* >(vertexBuffer);
00034 cl_int ciErrNum = CL_SUCCESS;
00035
00036 cl_mem clBuffer = openGLVertexBuffer->getBuffer();
00037 cl_kernel outputKernel = outputToVertexArrayWithNormalsKernel;
00038 if( !vertexBuffer->hasNormals() )
00039 outputKernel = outputToVertexArrayWithoutNormalsKernel;
00040
00041 ciErrNum = clEnqueueAcquireGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, NULL);
00042 if( ciErrNum != CL_SUCCESS )
00043 {
00044 btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)");
00045 }
00046
00047 int numVertices = currentCloth->getNumVertices();
00048
00049 ciErrNum = clSetKernelArg(outputKernel, 0, sizeof(int), &firstVertex );
00050 ciErrNum = clSetKernelArg(outputKernel, 1, sizeof(int), &numVertices );
00051 ciErrNum = clSetKernelArg(outputKernel, 2, sizeof(cl_mem), (void*)&clBuffer );
00052 if( vertexBuffer->hasVertexPositions() )
00053 {
00054 int vertexOffset = vertexBuffer->getVertexOffset();
00055 int vertexStride = vertexBuffer->getVertexStride();
00056 ciErrNum = clSetKernelArg(outputKernel, 3, sizeof(int), &vertexOffset );
00057 ciErrNum = clSetKernelArg(outputKernel, 4, sizeof(int), &vertexStride );
00058 ciErrNum = clSetKernelArg(outputKernel, 5, sizeof(cl_mem), (void*)&vertexData.m_clVertexPosition.m_buffer );
00059
00060 }
00061 if( vertexBuffer->hasNormals() )
00062 {
00063 int normalOffset = vertexBuffer->getNormalOffset();
00064 int normalStride = vertexBuffer->getNormalStride();
00065 ciErrNum = clSetKernelArg(outputKernel, 6, sizeof(int), &normalOffset );
00066 ciErrNum = clSetKernelArg(outputKernel, 7, sizeof(int), &normalStride );
00067 ciErrNum = clSetKernelArg(outputKernel, 8, sizeof(cl_mem), (void*)&vertexData.m_clVertexNormal.m_buffer );
00068
00069 }
00070 size_t numWorkItems = workGroupSize*((vertexData.getNumVertices() + (workGroupSize-1)) / workGroupSize);
00071 ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, outputKernel, 1, NULL, &numWorkItems, &workGroupSize,0 ,0 ,0);
00072 if( ciErrNum != CL_SUCCESS )
00073 {
00074 btAssert( 0 && "enqueueNDRangeKernel(copySoftBodyToVertexBuffer)");
00075 }
00076
00077 ciErrNum = clEnqueueReleaseGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, 0);
00078 if( ciErrNum != CL_SUCCESS )
00079 {
00080 btAssert( 0 && "clEnqueueReleaseGLObjects(copySoftBodyToVertexBuffer)");
00081 }
00082 } else {
00083 btAssert( "Undefined output for this solver output" == false );
00084 }
00085
00086
00087 clFinish(m_cqCommandQue);
00088
00089 }
00090
00091 bool btSoftBodySolverOutputCLtoGL::buildShaders()
00092 {
00093
00094 releaseKernels();
00095
00096 bool returnVal = true;
00097
00098 if( m_shadersInitialized )
00099 return true;
00100
00101 outputToVertexArrayWithNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl");
00102 outputToVertexArrayWithoutNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithoutNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl");
00103
00104
00105 if( returnVal )
00106 m_shadersInitialized = true;
00107
00108 return returnVal;
00109 }
00110
00111 void btSoftBodySolverOutputCLtoGL::releaseKernels()
00112 {
00113 RELEASE_CL_KERNEL( outputToVertexArrayWithNormalsKernel );
00114 RELEASE_CL_KERNEL( outputToVertexArrayWithoutNormalsKernel );
00115
00116 m_shadersInitialized = false;
00117 }
00118
00119 bool btSoftBodySolverOutputCLtoGL::checkInitialized()
00120 {
00121 if( !m_shadersInitialized )
00122 if( buildShaders() )
00123 m_shadersInitialized = true;
00124
00125 return m_shadersInitialized;
00126 }