root / rgbdslam / external / siftgpu / src / SiftGPU / CLTexImage.cpp @ 9240aaa3
History | View | Annotate | Download (6.81 KB)
1 | 9240aaa3 | Alex | ////////////////////////////////////////////////////////////////////////////
|
---|---|---|---|
2 | // 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 | //
|
||
20 | ////////////////////////////////////////////////////////////////////////////
|
||
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 | |||
144 | ////create the memory object
|
||
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 | |||
156 | ////acquire object
|
||
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
|