btSoftBodySolverOutputCLtoGL.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include "btSoftBodySolverOutputCLtoGL.h"
  2. #include <stdio.h> //@todo: remove the debugging printf at some stage
  3. #include "btSoftBodySolver_OpenCL.h"
  4. #include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
  5. #include "btSoftBodySolverVertexBuffer_OpenGL.h"
  6. #include "BulletSoftBody/btSoftBody.h"
  7. ////OpenCL 1.0 kernels don't use float3
  8. #define MSTRINGIFY(A) #A
  9. static char* OutputToVertexArrayCLString =
  10. #include "OpenCLC10/OutputToVertexArray.cl"
  11. #define RELEASE_CL_KERNEL(kernelName) {if( kernelName ){ clReleaseKernel( kernelName ); kernelName = 0; }}
  12. static const size_t workGroupSize = 128;
  13. void btSoftBodySolverOutputCLtoGL::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
  14. {
  15. btSoftBodySolver *solver = softBody->getSoftBodySolver();
  16. btAssert( solver->getSolverType() == btSoftBodySolver::CL_SOLVER || solver->getSolverType() == btSoftBodySolver::CL_SIMD_SOLVER );
  17. btOpenCLSoftBodySolver *dxSolver = static_cast< btOpenCLSoftBodySolver * >( solver );
  18. checkInitialized();
  19. btOpenCLAcceleratedSoftBodyInterface* currentCloth = dxSolver->findSoftBodyInterface( softBody );
  20. btSoftBodyVertexDataOpenCL &vertexData( dxSolver->m_vertexData );
  21. const int firstVertex = currentCloth->getFirstVertex();
  22. const int lastVertex = firstVertex + currentCloth->getNumVertices();
  23. if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::OPENGL_BUFFER ) {
  24. const btOpenGLInteropVertexBufferDescriptor *openGLVertexBuffer = static_cast< btOpenGLInteropVertexBufferDescriptor* >(vertexBuffer);
  25. cl_int ciErrNum = CL_SUCCESS;
  26. cl_mem clBuffer = openGLVertexBuffer->getBuffer();
  27. cl_kernel outputKernel = outputToVertexArrayWithNormalsKernel;
  28. if( !vertexBuffer->hasNormals() )
  29. outputKernel = outputToVertexArrayWithoutNormalsKernel;
  30. ciErrNum = clEnqueueAcquireGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, NULL);
  31. if( ciErrNum != CL_SUCCESS )
  32. {
  33. btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)");
  34. }
  35. int numVertices = currentCloth->getNumVertices();
  36. ciErrNum = clSetKernelArg(outputKernel, 0, sizeof(int), &firstVertex );
  37. ciErrNum = clSetKernelArg(outputKernel, 1, sizeof(int), &numVertices );
  38. ciErrNum = clSetKernelArg(outputKernel, 2, sizeof(cl_mem), (void*)&clBuffer );
  39. if( vertexBuffer->hasVertexPositions() )
  40. {
  41. int vertexOffset = vertexBuffer->getVertexOffset();
  42. int vertexStride = vertexBuffer->getVertexStride();
  43. ciErrNum = clSetKernelArg(outputKernel, 3, sizeof(int), &vertexOffset );
  44. ciErrNum = clSetKernelArg(outputKernel, 4, sizeof(int), &vertexStride );
  45. ciErrNum = clSetKernelArg(outputKernel, 5, sizeof(cl_mem), (void*)&vertexData.m_clVertexPosition.m_buffer );
  46. }
  47. if( vertexBuffer->hasNormals() )
  48. {
  49. int normalOffset = vertexBuffer->getNormalOffset();
  50. int normalStride = vertexBuffer->getNormalStride();
  51. ciErrNum = clSetKernelArg(outputKernel, 6, sizeof(int), &normalOffset );
  52. ciErrNum = clSetKernelArg(outputKernel, 7, sizeof(int), &normalStride );
  53. ciErrNum = clSetKernelArg(outputKernel, 8, sizeof(cl_mem), (void*)&vertexData.m_clVertexNormal.m_buffer );
  54. }
  55. size_t numWorkItems = workGroupSize*((vertexData.getNumVertices() + (workGroupSize-1)) / workGroupSize);
  56. ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, outputKernel, 1, NULL, &numWorkItems, &workGroupSize,0 ,0 ,0);
  57. if( ciErrNum != CL_SUCCESS )
  58. {
  59. btAssert( 0 && "enqueueNDRangeKernel(copySoftBodyToVertexBuffer)");
  60. }
  61. ciErrNum = clEnqueueReleaseGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, 0);
  62. if( ciErrNum != CL_SUCCESS )
  63. {
  64. btAssert( 0 && "clEnqueueReleaseGLObjects(copySoftBodyToVertexBuffer)");
  65. }
  66. } else {
  67. btAssert( "Undefined output for this solver output" == false );
  68. }
  69. // clFinish in here may not be the best thing. It's possible that we should have a waitForFrameComplete function.
  70. clFinish(m_cqCommandQue);
  71. } // btSoftBodySolverOutputCLtoGL::outputToVertexBuffers
  72. bool btSoftBodySolverOutputCLtoGL::buildShaders()
  73. {
  74. // Ensure current kernels are released first
  75. releaseKernels();
  76. bool returnVal = true;
  77. if( m_shadersInitialized )
  78. return true;
  79. outputToVertexArrayWithNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl");
  80. outputToVertexArrayWithoutNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithoutNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl");
  81. if( returnVal )
  82. m_shadersInitialized = true;
  83. return returnVal;
  84. } // btSoftBodySolverOutputCLtoGL::buildShaders
  85. void btSoftBodySolverOutputCLtoGL::releaseKernels()
  86. {
  87. RELEASE_CL_KERNEL( outputToVertexArrayWithNormalsKernel );
  88. RELEASE_CL_KERNEL( outputToVertexArrayWithoutNormalsKernel );
  89. m_shadersInitialized = false;
  90. } // btSoftBodySolverOutputCLtoGL::releaseKernels
  91. bool btSoftBodySolverOutputCLtoGL::checkInitialized()
  92. {
  93. if( !m_shadersInitialized )
  94. if( buildShaders() )
  95. m_shadersInitialized = true;
  96. return m_shadersInitialized;
  97. }