| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- /*
- Bullet Continuous Collision Detection and Physics Library
- Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
- 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.
- */
- #ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
- #define BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
- // OpenCL support
- #ifdef USE_MINICL
- #include "MiniCL/cl.h"
- #else //USE_MINICL
- #ifdef __APPLE__
- #include <OpenCL/OpenCL.h>
- #else
- #include <CL/cl.h>
- #endif //__APPLE__
- #endif//USE_MINICL
- #ifndef SAFE_RELEASE
- #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
- #endif
- template <typename ElementType> class btOpenCLBuffer
- {
- public:
- cl_command_queue m_cqCommandQue;
- cl_context m_clContext;
- cl_mem m_buffer;
- btAlignedObjectArray< ElementType > * m_CPUBuffer;
-
- int m_gpuSize;
- bool m_onGPU;
- bool m_readOnlyOnGPU;
- bool m_allocated;
- bool createBuffer( cl_mem* preexistingBuffer = 0)
- {
- cl_int err;
-
- if( preexistingBuffer )
- {
- m_buffer = *preexistingBuffer;
- }
- else {
- cl_mem_flags flags= m_readOnlyOnGPU ? CL_MEM_READ_ONLY : CL_MEM_READ_WRITE;
- size_t size = m_CPUBuffer->size() * sizeof(ElementType);
- // At a minimum the buffer must exist
- if( size == 0 )
- size = sizeof(ElementType);
- m_buffer = clCreateBuffer(m_clContext, flags, size, 0, &err);
- if( err != CL_SUCCESS )
- {
- btAssert( "Buffer::Buffer(m_buffer)");
- }
- }
- m_gpuSize = m_CPUBuffer->size();
- return true;
- }
- public:
- btOpenCLBuffer( cl_command_queue commandQue,cl_context ctx, btAlignedObjectArray< ElementType >* CPUBuffer, bool readOnly)
- :m_cqCommandQue(commandQue),
- m_clContext(ctx),
- m_buffer(0),
- m_CPUBuffer(CPUBuffer),
- m_gpuSize(0),
- m_onGPU(false),
- m_readOnlyOnGPU(readOnly),
- m_allocated(false)
- {
- }
- ~btOpenCLBuffer()
- {
- clReleaseMemObject(m_buffer);
- }
- bool moveToGPU()
- {
- cl_int err;
- if( (m_CPUBuffer->size() != m_gpuSize) )
- {
- m_onGPU = false;
- }
- if( !m_allocated && m_CPUBuffer->size() == 0 )
- {
- // If it isn't on the GPU and yet there is no data on the CPU side this may cause a problem with some kernels.
- // We should create *something* on the device side
- if (!createBuffer()) {
- return false;
- }
- m_allocated = true;
- }
- if( !m_onGPU && m_CPUBuffer->size() > 0 )
- {
- if (!m_allocated || (m_CPUBuffer->size() != m_gpuSize)) {
- if (!createBuffer()) {
- return false;
- }
- m_allocated = true;
- }
-
- size_t size = m_CPUBuffer->size() * sizeof(ElementType);
- err = clEnqueueWriteBuffer(m_cqCommandQue,m_buffer,
- CL_FALSE,
- 0,
- size,
- &((*m_CPUBuffer)[0]),0,0,0);
- if( err != CL_SUCCESS )
- {
- btAssert( "CommandQueue::enqueueWriteBuffer(m_buffer)" );
- }
- m_onGPU = true;
- }
- return true;
- }
- bool moveFromGPU()
- {
- cl_int err;
- if (m_CPUBuffer->size() > 0) {
- if (m_onGPU && !m_readOnlyOnGPU) {
- size_t size = m_CPUBuffer->size() * sizeof(ElementType);
- err = clEnqueueReadBuffer(m_cqCommandQue,
- m_buffer,
- CL_TRUE,
- 0,
- size,
- &((*m_CPUBuffer)[0]),0,0,0);
- if( err != CL_SUCCESS )
- {
- btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)" );
- }
- m_onGPU = false;
- }
- }
- return true;
- }
- bool copyFromGPU()
- {
- cl_int err;
- size_t size = m_CPUBuffer->size() * sizeof(ElementType);
- if (m_CPUBuffer->size() > 0) {
- if (m_onGPU && !m_readOnlyOnGPU) {
- err = clEnqueueReadBuffer(m_cqCommandQue,
- m_buffer,
- CL_TRUE,
- 0,size,
- &((*m_CPUBuffer)[0]),0,0,0);
- if( err != CL_SUCCESS )
- {
- btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)");
- }
- }
- }
- return true;
- }
- virtual void changedOnCPU()
- {
- m_onGPU = false;
- }
- }; // class btOpenCLBuffer
- #endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|