123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- #include "btSoftBodySolverOutputCLtoGL.h"
- #include <stdio.h> //@todo: remove the debugging printf at some stage
- #include "btSoftBodySolver_OpenCL.h"
- #include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
- #include "btSoftBodySolverVertexBuffer_OpenGL.h"
- #include "BulletSoftBody/btSoftBody.h"
- ////OpenCL 1.0 kernels don't use float3
- #define MSTRINGIFY(A) #A
- static char* OutputToVertexArrayCLString =
- #include "OpenCLC10/OutputToVertexArray.cl"
-
- #define RELEASE_CL_KERNEL(kernelName) {if( kernelName ){ clReleaseKernel( kernelName ); kernelName = 0; }}
- static const size_t workGroupSize = 128;
- void btSoftBodySolverOutputCLtoGL::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
- {
- btSoftBodySolver *solver = softBody->getSoftBodySolver();
- btAssert( solver->getSolverType() == btSoftBodySolver::CL_SOLVER || solver->getSolverType() == btSoftBodySolver::CL_SIMD_SOLVER );
- btOpenCLSoftBodySolver *dxSolver = static_cast< btOpenCLSoftBodySolver * >( solver );
- checkInitialized();
- btOpenCLAcceleratedSoftBodyInterface* currentCloth = dxSolver->findSoftBodyInterface( softBody );
- btSoftBodyVertexDataOpenCL &vertexData( dxSolver->m_vertexData );
- const int firstVertex = currentCloth->getFirstVertex();
- const int lastVertex = firstVertex + currentCloth->getNumVertices();
- if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::OPENGL_BUFFER ) {
- const btOpenGLInteropVertexBufferDescriptor *openGLVertexBuffer = static_cast< btOpenGLInteropVertexBufferDescriptor* >(vertexBuffer);
- cl_int ciErrNum = CL_SUCCESS;
- cl_mem clBuffer = openGLVertexBuffer->getBuffer();
- cl_kernel outputKernel = outputToVertexArrayWithNormalsKernel;
- if( !vertexBuffer->hasNormals() )
- outputKernel = outputToVertexArrayWithoutNormalsKernel;
- ciErrNum = clEnqueueAcquireGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, NULL);
- if( ciErrNum != CL_SUCCESS )
- {
- btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)");
- }
- int numVertices = currentCloth->getNumVertices();
- ciErrNum = clSetKernelArg(outputKernel, 0, sizeof(int), &firstVertex );
- ciErrNum = clSetKernelArg(outputKernel, 1, sizeof(int), &numVertices );
- ciErrNum = clSetKernelArg(outputKernel, 2, sizeof(cl_mem), (void*)&clBuffer );
- if( vertexBuffer->hasVertexPositions() )
- {
- int vertexOffset = vertexBuffer->getVertexOffset();
- int vertexStride = vertexBuffer->getVertexStride();
- ciErrNum = clSetKernelArg(outputKernel, 3, sizeof(int), &vertexOffset );
- ciErrNum = clSetKernelArg(outputKernel, 4, sizeof(int), &vertexStride );
- ciErrNum = clSetKernelArg(outputKernel, 5, sizeof(cl_mem), (void*)&vertexData.m_clVertexPosition.m_buffer );
- }
- if( vertexBuffer->hasNormals() )
- {
- int normalOffset = vertexBuffer->getNormalOffset();
- int normalStride = vertexBuffer->getNormalStride();
- ciErrNum = clSetKernelArg(outputKernel, 6, sizeof(int), &normalOffset );
- ciErrNum = clSetKernelArg(outputKernel, 7, sizeof(int), &normalStride );
- ciErrNum = clSetKernelArg(outputKernel, 8, sizeof(cl_mem), (void*)&vertexData.m_clVertexNormal.m_buffer );
- }
- size_t numWorkItems = workGroupSize*((vertexData.getNumVertices() + (workGroupSize-1)) / workGroupSize);
- ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, outputKernel, 1, NULL, &numWorkItems, &workGroupSize,0 ,0 ,0);
- if( ciErrNum != CL_SUCCESS )
- {
- btAssert( 0 && "enqueueNDRangeKernel(copySoftBodyToVertexBuffer)");
- }
- ciErrNum = clEnqueueReleaseGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, 0);
- if( ciErrNum != CL_SUCCESS )
- {
- btAssert( 0 && "clEnqueueReleaseGLObjects(copySoftBodyToVertexBuffer)");
- }
- } else {
- btAssert( "Undefined output for this solver output" == false );
- }
- // clFinish in here may not be the best thing. It's possible that we should have a waitForFrameComplete function.
- clFinish(m_cqCommandQue);
- } // btSoftBodySolverOutputCLtoGL::outputToVertexBuffers
- bool btSoftBodySolverOutputCLtoGL::buildShaders()
- {
- // Ensure current kernels are released first
- releaseKernels();
- bool returnVal = true;
- if( m_shadersInitialized )
- return true;
-
- outputToVertexArrayWithNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl");
- outputToVertexArrayWithoutNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithoutNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl");
- if( returnVal )
- m_shadersInitialized = true;
- return returnVal;
- } // btSoftBodySolverOutputCLtoGL::buildShaders
- void btSoftBodySolverOutputCLtoGL::releaseKernels()
- {
- RELEASE_CL_KERNEL( outputToVertexArrayWithNormalsKernel );
- RELEASE_CL_KERNEL( outputToVertexArrayWithoutNormalsKernel );
- m_shadersInitialized = false;
- } // btSoftBodySolverOutputCLtoGL::releaseKernels
- bool btSoftBodySolverOutputCLtoGL::checkInitialized()
- {
- if( !m_shadersInitialized )
- if( buildShaders() )
- m_shadersInitialized = true;
- return m_shadersInitialized;
- }
|