| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #if defined(CL_SIFTGPU_ENABLED) |
|
|
| #include "GL/glew.h" |
| #include <iostream> |
| #include <vector> |
| #include <algorithm> |
| #include <stdlib.h> |
| #include <math.h> |
| using namespace std; |
|
|
|
|
| #include <CL/OpenCL.h> |
| #include "CLTexImage.h" |
| #include "ProgramCL.h" |
| #include "GlobalUtil.h" |
|
|
|
|
| CLTexImage::CLTexImage() |
| { |
| _context = NULL; |
| _queue = NULL; |
| _clData = NULL; |
| _numChannel = _bufferLen = _fromGL = 0; |
| _imgWidth = _imgHeight = _texWidth = _texHeight = 0; |
| } |
|
|
| CLTexImage::CLTexImage(cl_context context, cl_command_queue queue) |
| { |
| _context = context; |
| _queue = queue; |
| _clData = NULL; |
| _numChannel = _bufferLen = _fromGL = 0; |
| _imgWidth = _imgHeight = _texWidth = _texHeight = 0; |
| } |
|
|
| void CLTexImage::SetContext(cl_context context, cl_command_queue queue) |
| { |
| _context = context; |
| _queue = queue; |
| } |
|
|
|
|
| CLTexImage::~CLTexImage() |
| { |
| ReleaseTexture(); |
| } |
|
|
| void CLTexImage::ReleaseTexture() |
| { |
| if(_fromGL) clEnqueueReleaseGLObjects(_queue, 1, &_clData, 0, NULL, NULL); |
| if(_clData) clReleaseMemObject(_clData); |
| } |
|
|
| void CLTexImage::SetImageSize(int width, int height) |
| { |
| _imgWidth = width; |
| _imgHeight = height; |
| } |
|
|
| void CLTexImage::InitBufferTex(int width, int height, int nchannel) |
| { |
| if(width == 0 || height == 0 || nchannel <= 0 || _fromGL) return; |
|
|
| _imgWidth = width; _imgHeight = height; |
| _texWidth = _texHeight = _fromGL = 0; |
| _numChannel = min(nchannel, 4); |
|
|
| int size = width * height * _numChannel * sizeof(float); |
| if (size <= _bufferLen) return; |
| |
| |
| cl_int status; |
| if(_clData) status = clReleaseMemObject(_clData); |
|
|
| _clData = clCreateBuffer(_context, CL_MEM_READ_WRITE, |
| _bufferLen = size, NULL, &status); |
|
|
| ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitBufferTex"); |
|
|
| } |
|
|
| void CLTexImage::InitTexture(int width, int height, int nchannel) |
| { |
| if(width == 0 || height == 0 || nchannel <= 0 || _fromGL) return; |
| if(_clData && width == _texWidth && height == _texHeight && _numChannel == nchannel) return; |
| if(_clData) clReleaseMemObject(_clData); |
|
|
| _texWidth = _imgWidth = width; |
| _texHeight = _imgHeight = height; |
| _numChannel = nchannel; |
| _bufferLen = _fromGL = 0; |
|
|
| cl_int status; cl_image_format format; |
|
|
| if(nchannel == 1) format.image_channel_order = CL_R; |
| else if(nchannel == 2) format.image_channel_order = CL_RG; |
| else if(nchannel == 3) format.image_channel_order = CL_RGB; |
| else format.image_channel_order = CL_RGBA; |
|
|
| format.image_channel_data_type = CL_FLOAT; |
| _clData = clCreateImage2D(_context, CL_MEM_READ_WRITE, & format, |
| _texWidth, _texHeight, 0, 0, &status); |
| ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTexture"); |
| } |
|
|
| void CLTexImage::InitPackedTex(int width, int height, int packed) |
| { |
| if(packed) InitTexture((width + 1) >> 1, (height + 1) >> 1, 4); |
| else InitTexture(width, height, 1); |
| } |
|
|
| void CLTexImage::SetPackedSize(int width, int height, int packed) |
| { |
| if(packed) SetImageSize((width + 1) >> 1, (height + 1) >> 1); |
| else SetImageSize(width, height); |
| } |
|
|
| void CLTexImage::InitTextureGL(GLuint tex, int width, int height, int nchannel) |
| { |
| if(tex == 0) return; |
| if(_clData) clReleaseMemObject(_clData); |
|
|
| |
| cl_int status; |
| _clData = clCreateFromGLTexture2D(_context, CL_MEM_WRITE_ONLY, |
| GlobalUtil::_texTarget, 0 , tex, &status); |
| ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTextureGL->clCreateFromGLTexture2D"); |
| if(status != CL_SUCCESS) return; |
|
|
| _texWidth = _imgWidth = width; |
| _texHeight = _imgHeight = height; |
| _numChannel = nchannel; |
| _bufferLen = 0; _fromGL = 1; |
|
|
| |
| status = clEnqueueAcquireGLObjects(_queue, 1, &_clData, 0, NULL, NULL); |
| ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTextureGL->clEnqueueAcquireGLObjects"); |
|
|
| } |
|
|
| void CLTexImage::CopyFromHost(const void * buf) |
| { |
| if(_clData == NULL) return; |
| cl_int status; |
| if(_bufferLen) |
| { |
| status = clEnqueueWriteBuffer(_queue, _clData, false, 0, |
| _imgWidth * _imgHeight * _numChannel * sizeof(float), buf, 0, NULL, NULL); |
| }else |
| { |
| size_t origin[3] = {0, 0, 0}, region[3] = {_imgWidth, _imgHeight, 1}; |
| size_t row_pitch = _imgWidth * _numChannel * sizeof(float); |
| status = clEnqueueWriteImage(_queue, _clData, false, origin, |
| region, row_pitch, 0, buf, 0, 0, 0); |
| } |
| ProgramBagCL::CheckErrorCL(status, "CLTexImage::CopyFromHost"); |
| } |
|
|
| int CLTexImage::GetImageDataSize() |
| { |
| return _imgWidth * _imgHeight * _numChannel * sizeof(float); |
| } |
|
|
| int CLTexImage::CopyToPBO(GLuint pbo) |
| { |
| glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); |
|
|
| int esize = GetImageDataSize(), bsize; |
| glGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); |
| if(bsize < esize) |
| { |
| glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, esize, NULL, GL_STATIC_DRAW_ARB); |
| glGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); |
| } |
| if(bsize >= esize) |
| { |
| |
| void* ptr = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); |
| CopyToHost(ptr); |
| clFinish(_queue); |
| glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); |
| } |
| glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); |
| GlobalUtil::CheckErrorsGL("CLTexImage::CopyToPBO"); |
| return esize >= bsize; |
| } |
|
|
| void CLTexImage::CopyToHost(void * buf) |
| { |
| if(_clData == NULL) return; |
| cl_int status; |
| if(_bufferLen) |
| { |
| status = clEnqueueReadBuffer(_queue, _clData, true, 0, |
| _imgWidth * _imgHeight * _numChannel * sizeof(float), buf, 0, NULL, NULL); |
| }else |
| { |
| size_t origin[3] = {0, 0, 0}, region[3] = {_imgWidth, _imgHeight, 1}; |
| size_t row_pitch = _imgWidth * _numChannel * sizeof(float); |
| status = clEnqueueReadImage(_queue, _clData, true, origin, |
| region, row_pitch, 0, buf, 0, 0, 0); |
| } |
|
|
| ProgramBagCL::CheckErrorCL(status, "CLTexImage::CopyToHost"); |
| } |
|
|
| #endif |
|
|
|
|