ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
CLTexImage.cpp
Go to the documentation of this file.
1 // File: CLTexImage.cpp
3 // Author: Changchang Wu
4 // Description : implementation of the CLTexImage class.
5 //
6 // Copyright (c) 2007 University of North Carolina at Chapel Hill
7 // All Rights Reserved
8 //
9 // Permission to use, copy, modify and distribute this software and its
10 // documentation for educational, research and non-profit purposes, without
11 // fee, and without a written agreement is hereby granted, provided that the
12 // above copyright notice and the following paragraph appear in all copies.
13 //
14 // The University of North Carolina at Chapel Hill make no representations
15 // about the suitability of this software for any purpose. It is provided
16 // 'as is' without express or implied warranty.
17 //
18 // Please send BUG REPORTS to ccwu@cs.unc.edu
19 //
21 
22 #if defined(CL_SIFTGPU_ENABLED)
23 
24 #include "GL/glew.h"
25 #include <iostream>
26 #include <vector>
27 #include <algorithm>
28 #include <stdlib.h>
29 #include <math.h>
30 using namespace std;
31 
32 
33 #include <CL/OpenCL.h>
34 #include "CLTexImage.h"
35 #include "ProgramCL.h"
36 #include "GlobalUtil.h"
37 
38 
39 CLTexImage::CLTexImage()
40 {
41  _context = NULL;
42  _queue = NULL;
43  _clData = NULL;
44  _numChannel = _bufferLen = _fromGL = 0;
45  _imgWidth = _imgHeight = _texWidth = _texHeight = 0;
46 }
47 
48 CLTexImage::CLTexImage(cl_context context, cl_command_queue queue)
49 {
50  _context = context;
51  _queue = queue;
52  _clData = NULL;
53  _numChannel = _bufferLen = _fromGL = 0;
54  _imgWidth = _imgHeight = _texWidth = _texHeight = 0;
55 }
56 
57 void CLTexImage::SetContext(cl_context context, cl_command_queue queue)
58 {
59  _context = context;
60  _queue = queue;
61 }
62 
63 
64 CLTexImage::~CLTexImage()
65 {
66  ReleaseTexture();
67 }
68 
69 void CLTexImage::ReleaseTexture()
70 {
71  if(_fromGL) clEnqueueReleaseGLObjects(_queue, 1, &_clData, 0, NULL, NULL);
72  if(_clData) clReleaseMemObject(_clData);
73 }
74 
75 void CLTexImage::SetImageSize(int width, int height)
76 {
77  _imgWidth = width;
78  _imgHeight = height;
79 }
80 
81 void CLTexImage::InitBufferTex(int width, int height, int nchannel)
82 {
83  if(width == 0 || height == 0 || nchannel <= 0 || _fromGL) return;
84 
85  _imgWidth = width; _imgHeight = height;
86  _texWidth = _texHeight = _fromGL = 0;
87  _numChannel = min(nchannel, 4);
88 
89  int size = width * height * _numChannel * sizeof(float);
90  if (size <= _bufferLen) return;
91 
92  //allocate the buffer data
93  cl_int status;
94  if(_clData) status = clReleaseMemObject(_clData);
95 
96  _clData = clCreateBuffer(_context, CL_MEM_READ_WRITE,
97  _bufferLen = size, NULL, &status);
98 
99  ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitBufferTex");
100 
101 }
102 
103 void CLTexImage::InitTexture(int width, int height, int nchannel)
104 {
105  if(width == 0 || height == 0 || nchannel <= 0 || _fromGL) return;
106  if(_clData && width == _texWidth && height == _texHeight && _numChannel == nchannel) return;
107  if(_clData) clReleaseMemObject(_clData);
108 
109  _texWidth = _imgWidth = width;
110  _texHeight = _imgHeight = height;
111  _numChannel = nchannel;
112  _bufferLen = _fromGL = 0;
113 
114  cl_int status; cl_image_format format;
115 
116  if(nchannel == 1) format.image_channel_order = CL_R;
117  else if(nchannel == 2) format.image_channel_order = CL_RG;
118  else if(nchannel == 3) format.image_channel_order = CL_RGB;
119  else format.image_channel_order = CL_RGBA;
120 
121  format.image_channel_data_type = CL_FLOAT;
122  _clData = clCreateImage2D(_context, CL_MEM_READ_WRITE, & format,
123  _texWidth, _texHeight, 0, 0, &status);
124  ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTexture");
125 }
126 
127 void CLTexImage::InitPackedTex(int width, int height, int packed)
128 {
129  if(packed) InitTexture((width + 1) >> 1, (height + 1) >> 1, 4);
130  else InitTexture(width, height, 1);
131 }
132 
133 void CLTexImage::SetPackedSize(int width, int height, int packed)
134 {
135  if(packed) SetImageSize((width + 1) >> 1, (height + 1) >> 1);
136  else SetImageSize(width, height);
137 }
138 
139 void CLTexImage::InitTextureGL(GLuint tex, int width, int height, int nchannel)
140 {
141  if(tex == 0) return;
142  if(_clData) clReleaseMemObject(_clData);
143 
145  cl_int status;
146  _clData = clCreateFromGLTexture2D(_context, CL_MEM_WRITE_ONLY,
147  GlobalUtil::_texTarget, 0 , tex, &status);
148  ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTextureGL->clCreateFromGLTexture2D");
149  if(status != CL_SUCCESS) return;
150 
151  _texWidth = _imgWidth = width;
152  _texHeight = _imgHeight = height;
153  _numChannel = nchannel;
154  _bufferLen = 0; _fromGL = 1;
155 
157  status = clEnqueueAcquireGLObjects(_queue, 1, &_clData, 0, NULL, NULL);
158  ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTextureGL->clEnqueueAcquireGLObjects");
159 
160 }
161 
162 void CLTexImage::CopyFromHost(const void * buf)
163 {
164  if(_clData == NULL) return;
165  cl_int status;
166  if(_bufferLen)
167  {
168  status = clEnqueueWriteBuffer(_queue, _clData, false, 0,
169  _imgWidth * _imgHeight * _numChannel * sizeof(float), buf, 0, NULL, NULL);
170  }else
171  {
172  size_t origin[3] = {0, 0, 0}, region[3] = {_imgWidth, _imgHeight, 1};
173  size_t row_pitch = _imgWidth * _numChannel * sizeof(float);
174  status = clEnqueueWriteImage(_queue, _clData, false, origin,
175  region, row_pitch, 0, buf, 0, 0, 0);
176  }
177  ProgramBagCL::CheckErrorCL(status, "CLTexImage::CopyFromHost");
178 }
179 
180 int CLTexImage::GetImageDataSize()
181 {
182  return _imgWidth * _imgHeight * _numChannel * sizeof(float);
183 }
184 
185 int CLTexImage::CopyToPBO(GLuint pbo)
186 {
187  glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
188 
189  int esize = GetImageDataSize(), bsize;
190  glGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
191  if(bsize < esize)
192  {
193  glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, esize, NULL, GL_STATIC_DRAW_ARB);
194  glGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
195  }
196  if(bsize >= esize)
197  {
198  // map the buffer object into client's memory
199  void* ptr = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
200  CopyToHost(ptr);
201  clFinish(_queue);
202  glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
203  }
204  glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
205  GlobalUtil::CheckErrorsGL("CLTexImage::CopyToPBO");
206  return esize >= bsize;
207 }
208 
209 void CLTexImage::CopyToHost(void * buf)
210 {
211  if(_clData == NULL) return;
212  cl_int status;
213  if(_bufferLen)
214  {
215  status = clEnqueueReadBuffer(_queue, _clData, true, 0,
216  _imgWidth * _imgHeight * _numChannel * sizeof(float), buf, 0, NULL, NULL);
217  }else
218  {
219  size_t origin[3] = {0, 0, 0}, region[3] = {_imgWidth, _imgHeight, 1};
220  size_t row_pitch = _imgWidth * _numChannel * sizeof(float);
221  status = clEnqueueReadImage(_queue, _clData, true, origin,
222  region, row_pitch, 0, buf, 0, 0, 0);
223  }
224 
225  ProgramBagCL::CheckErrorCL(status, "CLTexImage::CopyToHost");
226 }
227 
228 #endif
229 
filament::Texture::InternalFormat format
int width
int size
int height
#define NULL
static GLuint _texTarget
Definition: GlobalUtil.h:37
static void CheckErrorsGL(const char *location=NULL)
Definition: GlobalUtil.h:137
int min(int a, int b)
Definition: cutil_math.h:53
ImGuiContext * context
Definition: Window.cpp:76
Definition: Eigen.h:85