Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
00017 #define BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
00018
00019
00020
00021 #ifdef USE_MINICL
00022 #include "MiniCL/cl.h"
00023 #else //USE_MINICL
00024 #ifdef __APPLE__
00025 #include <OpenCL/OpenCL.h>
00026 #else
00027 #include <CL/cl.h>
00028 #endif //__APPLE__
00029 #endif//USE_MINICL
00030
00031 #ifndef SAFE_RELEASE
00032 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
00033 #endif
00034
00035 template <typename ElementType> class btOpenCLBuffer
00036 {
00037 public:
00038
00039 cl_command_queue m_cqCommandQue;
00040 cl_context m_clContext;
00041 cl_mem m_buffer;
00042
00043
00044
00045 btAlignedObjectArray< ElementType > * m_CPUBuffer;
00046
00047 int m_gpuSize;
00048 bool m_onGPU;
00049 bool m_readOnlyOnGPU;
00050 bool m_allocated;
00051
00052
00053 bool createBuffer( cl_mem* preexistingBuffer = 0)
00054 {
00055
00056 cl_int err;
00057
00058
00059 if( preexistingBuffer )
00060 {
00061 m_buffer = *preexistingBuffer;
00062 }
00063 else {
00064
00065 cl_mem_flags flags= m_readOnlyOnGPU ? CL_MEM_READ_ONLY : CL_MEM_READ_WRITE;
00066
00067 size_t size = m_CPUBuffer->size() * sizeof(ElementType);
00068
00069 if( size == 0 )
00070 size = sizeof(ElementType);
00071 m_buffer = clCreateBuffer(m_clContext, flags, size, 0, &err);
00072 if( err != CL_SUCCESS )
00073 {
00074 btAssert( "Buffer::Buffer(m_buffer)");
00075 }
00076 }
00077
00078 m_gpuSize = m_CPUBuffer->size();
00079
00080 return true;
00081 }
00082
00083 public:
00084 btOpenCLBuffer( cl_command_queue commandQue,cl_context ctx, btAlignedObjectArray< ElementType >* CPUBuffer, bool readOnly)
00085 :m_cqCommandQue(commandQue),
00086 m_clContext(ctx),
00087 m_buffer(0),
00088 m_CPUBuffer(CPUBuffer),
00089 m_gpuSize(0),
00090 m_onGPU(false),
00091 m_readOnlyOnGPU(readOnly),
00092 m_allocated(false)
00093 {
00094 }
00095
00096 ~btOpenCLBuffer()
00097 {
00098 clReleaseMemObject(m_buffer);
00099 }
00100
00101
00102 bool moveToGPU()
00103 {
00104
00105
00106 cl_int err;
00107
00108 if( (m_CPUBuffer->size() != m_gpuSize) )
00109 {
00110 m_onGPU = false;
00111 }
00112
00113 if( !m_allocated && m_CPUBuffer->size() == 0 )
00114 {
00115
00116
00117 if (!createBuffer()) {
00118 return false;
00119 }
00120 m_allocated = true;
00121 }
00122
00123 if( !m_onGPU && m_CPUBuffer->size() > 0 )
00124 {
00125 if (!m_allocated || (m_CPUBuffer->size() != m_gpuSize)) {
00126 if (!createBuffer()) {
00127 return false;
00128 }
00129 m_allocated = true;
00130 }
00131
00132 size_t size = m_CPUBuffer->size() * sizeof(ElementType);
00133 err = clEnqueueWriteBuffer(m_cqCommandQue,m_buffer,
00134 CL_FALSE,
00135 0,
00136 size,
00137 &((*m_CPUBuffer)[0]),0,0,0);
00138 if( err != CL_SUCCESS )
00139 {
00140 btAssert( "CommandQueue::enqueueWriteBuffer(m_buffer)" );
00141 }
00142
00143 m_onGPU = true;
00144 }
00145
00146 return true;
00147
00148 }
00149
00150 bool moveFromGPU()
00151 {
00152
00153 cl_int err;
00154
00155 if (m_CPUBuffer->size() > 0) {
00156 if (m_onGPU && !m_readOnlyOnGPU) {
00157 size_t size = m_CPUBuffer->size() * sizeof(ElementType);
00158 err = clEnqueueReadBuffer(m_cqCommandQue,
00159 m_buffer,
00160 CL_TRUE,
00161 0,
00162 size,
00163 &((*m_CPUBuffer)[0]),0,0,0);
00164
00165 if( err != CL_SUCCESS )
00166 {
00167 btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)" );
00168 }
00169
00170 m_onGPU = false;
00171 }
00172 }
00173
00174 return true;
00175 }
00176
00177 bool copyFromGPU()
00178 {
00179
00180 cl_int err;
00181 size_t size = m_CPUBuffer->size() * sizeof(ElementType);
00182
00183 if (m_CPUBuffer->size() > 0) {
00184 if (m_onGPU && !m_readOnlyOnGPU) {
00185 err = clEnqueueReadBuffer(m_cqCommandQue,
00186 m_buffer,
00187 CL_TRUE,
00188 0,size,
00189 &((*m_CPUBuffer)[0]),0,0,0);
00190
00191 if( err != CL_SUCCESS )
00192 {
00193 btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)");
00194 }
00195
00196 }
00197 }
00198
00199 return true;
00200 }
00201
00202 virtual void changedOnCPU()
00203 {
00204 m_onGPU = false;
00205 }
00206 };
00207
00208
00209 #endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H