00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00021
00022 #if defined(CL_SIFTGPU_ENABLED)
00023
00024 #include "GL/glew.h"
00025 #include <iostream>
00026 #include <vector>
00027 #include <algorithm>
00028 #include <stdlib.h>
00029 #include <math.h>
00030 using namespace std;
00031
00032
00033 #include <CL/OpenCL.h>
00034 #include "CLTexImage.h"
00035 #include "ProgramCL.h"
00036 #include "GlobalUtil.h"
00037
00038
00039 CLTexImage::CLTexImage()
00040 {
00041 _context = NULL;
00042 _queue = NULL;
00043 _clData = NULL;
00044 _numChannel = _bufferLen = _fromGL = 0;
00045 _imgWidth = _imgHeight = _texWidth = _texHeight = 0;
00046 }
00047
00048 CLTexImage::CLTexImage(cl_context context, cl_command_queue queue)
00049 {
00050 _context = context;
00051 _queue = queue;
00052 _clData = NULL;
00053 _numChannel = _bufferLen = _fromGL = 0;
00054 _imgWidth = _imgHeight = _texWidth = _texHeight = 0;
00055 }
00056
00057 void CLTexImage::SetContext(cl_context context, cl_command_queue queue)
00058 {
00059 _context = context;
00060 _queue = queue;
00061 }
00062
00063
00064 CLTexImage::~CLTexImage()
00065 {
00066 ReleaseTexture();
00067 }
00068
00069 void CLTexImage::ReleaseTexture()
00070 {
00071 if(_fromGL) clEnqueueReleaseGLObjects(_queue, 1, &_clData, 0, NULL, NULL);
00072 if(_clData) clReleaseMemObject(_clData);
00073 }
00074
00075 void CLTexImage::SetImageSize(int width, int height)
00076 {
00077 _imgWidth = width;
00078 _imgHeight = height;
00079 }
00080
00081 void CLTexImage::InitBufferTex(int width, int height, int nchannel)
00082 {
00083 if(width == 0 || height == 0 || nchannel <= 0 || _fromGL) return;
00084
00085 _imgWidth = width; _imgHeight = height;
00086 _texWidth = _texHeight = _fromGL = 0;
00087 _numChannel = min(nchannel, 4);
00088
00089 int size = width * height * _numChannel * sizeof(float);
00090 if (size <= _bufferLen) return;
00091
00092
00093 cl_int status;
00094 if(_clData) status = clReleaseMemObject(_clData);
00095
00096 _clData = clCreateBuffer(_context, CL_MEM_READ_WRITE,
00097 _bufferLen = size, NULL, &status);
00098
00099 ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitBufferTex");
00100
00101 }
00102
00103 void CLTexImage::InitTexture(int width, int height, int nchannel)
00104 {
00105 if(width == 0 || height == 0 || nchannel <= 0 || _fromGL) return;
00106 if(_clData && width == _texWidth && height == _texHeight && _numChannel == nchannel) return;
00107 if(_clData) clReleaseMemObject(_clData);
00108
00109 _texWidth = _imgWidth = width;
00110 _texHeight = _imgHeight = height;
00111 _numChannel = nchannel;
00112 _bufferLen = _fromGL = 0;
00113
00114 cl_int status; cl_image_format format;
00115
00116 if(nchannel == 1) format.image_channel_order = CL_R;
00117 else if(nchannel == 2) format.image_channel_order = CL_RG;
00118 else if(nchannel == 3) format.image_channel_order = CL_RGB;
00119 else format.image_channel_order = CL_RGBA;
00120
00121 format.image_channel_data_type = CL_FLOAT;
00122 _clData = clCreateImage2D(_context, CL_MEM_READ_WRITE, & format,
00123 _texWidth, _texHeight, 0, 0, &status);
00124 ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTexture");
00125 }
00126
00127 void CLTexImage::InitPackedTex(int width, int height, int packed)
00128 {
00129 if(packed) InitTexture((width + 1) >> 1, (height + 1) >> 1, 4);
00130 else InitTexture(width, height, 1);
00131 }
00132
00133 void CLTexImage::SetPackedSize(int width, int height, int packed)
00134 {
00135 if(packed) SetImageSize((width + 1) >> 1, (height + 1) >> 1);
00136 else SetImageSize(width, height);
00137 }
00138
00139 void CLTexImage::InitTextureGL(GLuint tex, int width, int height, int nchannel)
00140 {
00141 if(tex == 0) return;
00142 if(_clData) clReleaseMemObject(_clData);
00143
00145 cl_int status;
00146 _clData = clCreateFromGLTexture2D(_context, CL_MEM_WRITE_ONLY,
00147 GlobalUtil::_texTarget, 0 , tex, &status);
00148 ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTextureGL->clCreateFromGLTexture2D");
00149 if(status != CL_SUCCESS) return;
00150
00151 _texWidth = _imgWidth = width;
00152 _texHeight = _imgHeight = height;
00153 _numChannel = nchannel;
00154 _bufferLen = 0; _fromGL = 1;
00155
00157 status = clEnqueueAcquireGLObjects(_queue, 1, &_clData, 0, NULL, NULL);
00158 ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTextureGL->clEnqueueAcquireGLObjects");
00159
00160 }
00161
00162 void CLTexImage::CopyFromHost(const void * buf)
00163 {
00164 if(_clData == NULL) return;
00165 cl_int status;
00166 if(_bufferLen)
00167 {
00168 status = clEnqueueWriteBuffer(_queue, _clData, false, 0,
00169 _imgWidth * _imgHeight * _numChannel * sizeof(float), buf, 0, NULL, NULL);
00170 }else
00171 {
00172 size_t origin[3] = {0, 0, 0}, region[3] = {_imgWidth, _imgHeight, 1};
00173 size_t row_pitch = _imgWidth * _numChannel * sizeof(float);
00174 status = clEnqueueWriteImage(_queue, _clData, false, origin,
00175 region, row_pitch, 0, buf, 0, 0, 0);
00176 }
00177 ProgramBagCL::CheckErrorCL(status, "CLTexImage::CopyFromHost");
00178 }
00179
00180 int CLTexImage::GetImageDataSize()
00181 {
00182 return _imgWidth * _imgHeight * _numChannel * sizeof(float);
00183 }
00184
00185 int CLTexImage::CopyToPBO(GLuint pbo)
00186 {
00187 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
00188
00189 int esize = GetImageDataSize(), bsize;
00190 glGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
00191 if(bsize < esize)
00192 {
00193 glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, esize, NULL, GL_STATIC_DRAW_ARB);
00194 glGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
00195 }
00196 if(bsize >= esize)
00197 {
00198
00199 void* ptr = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
00200 CopyToHost(ptr);
00201 clFinish(_queue);
00202 glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
00203 }
00204 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
00205 GlobalUtil::CheckErrorsGL("CLTexImage::CopyToPBO");
00206 return esize >= bsize;
00207 }
00208
00209 void CLTexImage::CopyToHost(void * buf)
00210 {
00211 if(_clData == NULL) return;
00212 cl_int status;
00213 if(_bufferLen)
00214 {
00215 status = clEnqueueReadBuffer(_queue, _clData, true, 0,
00216 _imgWidth * _imgHeight * _numChannel * sizeof(float), buf, 0, NULL, NULL);
00217 }else
00218 {
00219 size_t origin[3] = {0, 0, 0}, region[3] = {_imgWidth, _imgHeight, 1};
00220 size_t row_pitch = _imgWidth * _numChannel * sizeof(float);
00221 status = clEnqueueReadImage(_queue, _clData, true, origin,
00222 region, row_pitch, 0, buf, 0, 0, 0);
00223 }
00224
00225 ProgramBagCL::CheckErrorCL(status, "CLTexImage::CopyToHost");
00226 }
00227
00228 #endif
00229