Statistics
| Branch: | Revision:

root / rgbdslam / external / siftgpu / src / SiftGPU / CLTexImage.cpp @ 9240aaa3

History | View | Annotate | Download (6.81 KB)

1
////////////////////////////////////////////////////////////////////////////
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
229