You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
6.8 KiB
230 lines
6.8 KiB
////////////////////////////////////////////////////////////////////////////
|
|
// File: CLTexImage.cpp
|
|
// Author: Changchang Wu
|
|
// Description : implementation of the CLTexImage class.
|
|
//
|
|
// Copyright (c) 2007 University of North Carolina at Chapel Hill
|
|
// All Rights Reserved
|
|
//
|
|
// Permission to use, copy, modify and distribute this software and its
|
|
// documentation for educational, research and non-profit purposes, without
|
|
// fee, and without a written agreement is hereby granted, provided that the
|
|
// above copyright notice and the following paragraph appear in all copies.
|
|
//
|
|
// The University of North Carolina at Chapel Hill make no representations
|
|
// about the suitability of this software for any purpose. It is provided
|
|
// 'as is' without express or implied warranty.
|
|
//
|
|
// Please send BUG REPORTS to ccwu@cs.unc.edu
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#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;
|
|
|
|
//allocate the buffer data
|
|
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);
|
|
|
|
////create the memory object
|
|
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;
|
|
|
|
////acquire object
|
|
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)
|
|
{
|
|
// map the buffer object into client's memory
|
|
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
|
|
|