CLTexImage.cpp
Go to the documentation of this file.
00001 
00002 //      File:           CLTexImage.cpp
00003 //      Author:         Changchang Wu
00004 //      Description : implementation of the CLTexImage class.
00005 //
00006 //      Copyright (c) 2007 University of North Carolina at Chapel Hill
00007 //      All Rights Reserved
00008 //
00009 //      Permission to use, copy, modify and distribute this software and its
00010 //      documentation for educational, research and non-profit purposes, without
00011 //      fee, and without a written agreement is hereby granted, provided that the
00012 //      above copyright notice and the following paragraph appear in all copies.
00013 //      
00014 //      The University of North Carolina at Chapel Hill make no representations
00015 //      about the suitability of this software for any purpose. It is provided
00016 //      'as is' without express or implied warranty. 
00017 //
00018 //      Please send BUG REPORTS to ccwu@cs.unc.edu
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         //allocate the buffer data
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         // map the buffer object into client's memory
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 


siftgpu
Author(s): Changchang Wu (library), Bence Magyar (ROS wrapper)
autogenerated on Thu Jan 2 2014 11:38:01