00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef PANGOLIN_CUDAGL_H
00029 #define PANGOLIN_CUDAGL_H
00030
00031 #include <algorithm>
00032 #include <cuda_runtime.h>
00033 #include <cuda_gl_interop.h>
00034
00035 #include "gl.h"
00036
00037 namespace pangolin
00038 {
00039
00041
00043
00044 enum GlBufferType
00045 {
00046 GlArrayBuffer = GL_ARRAY_BUFFER,
00047 GlElementArrayBuffer = GL_ELEMENT_ARRAY_BUFFER,
00048 GlPixelPackBuffer = GL_PIXEL_PACK_BUFFER,
00049 GlPixelUnpackBuffer = GL_PIXEL_UNPACK_BUFFER
00050 };
00051
00052 struct GlBufferCudaPtr
00053 {
00054 GlBufferCudaPtr(GlBufferType buffer_type, GLsizeiptr size_bytes, unsigned int cudause = cudaGraphicsMapFlagsNone, GLenum gluse = GL_DYNAMIC_DRAW );
00055 ~GlBufferCudaPtr();
00056 void Bind() const;
00057 void Unbind() const;
00058 void Upload(const GLvoid* data, GLsizeiptr size_bytes, GLintptr offset = 0);
00059 GLuint bo;
00060 cudaGraphicsResource* cuda_res;
00061 GlBufferType buffer_type;
00062
00063 private:
00064 GlBufferCudaPtr(const GlBufferCudaPtr&) {}
00065 };
00066
00067 struct GlTextureCudaArray : GlTexture
00068 {
00069 GlTextureCudaArray(int width, int height, GLint internal_format);
00070 ~GlTextureCudaArray();
00071 cudaGraphicsResource* cuda_res;
00072 };
00073
00074 struct CudaScopedMappedPtr
00075 {
00076 CudaScopedMappedPtr(GlBufferCudaPtr& buffer);
00077 ~CudaScopedMappedPtr();
00078 void* operator*();
00079 cudaGraphicsResource* res;
00080
00081 private:
00082 CudaScopedMappedPtr(const CudaScopedMappedPtr&) {}
00083 };
00084
00085 struct CudaScopedMappedArray
00086 {
00087 CudaScopedMappedArray(GlTextureCudaArray& tex);
00088 ~CudaScopedMappedArray();
00089 cudaArray* operator*();
00090 cudaGraphicsResource* res;
00091
00092 private:
00093 CudaScopedMappedArray(const CudaScopedMappedArray&) {}
00094 };
00095
00096 void CopyPboToTex(GlBufferCudaPtr& buffer, GlTexture& tex);
00097
00098 void swap(GlBufferCudaPtr& a, GlBufferCudaPtr& b);
00099
00101
00103
00104 inline GlBufferCudaPtr::GlBufferCudaPtr(GlBufferType buffer_type, GLsizeiptr size_bytes, unsigned int cudause, GLenum gluse)
00105 : buffer_type(buffer_type)
00106 {
00107 glGenBuffers(1, &bo);
00108 Bind();
00109 glBufferData(buffer_type, size_bytes, 0, gluse);
00110 Unbind();
00111 cudaGraphicsGLRegisterBuffer( &cuda_res, bo, cudause );
00112 }
00113
00114 inline GlBufferCudaPtr::~GlBufferCudaPtr()
00115 {
00116 cudaGraphicsUnregisterResource(cuda_res);
00117 glDeleteBuffers(1, &bo);
00118 }
00119
00120 inline void GlBufferCudaPtr::Bind() const
00121 {
00122 glBindBuffer(buffer_type, bo);
00123 }
00124
00125 inline void GlBufferCudaPtr::Unbind() const
00126 {
00127 glBindBuffer(buffer_type, 0);
00128 }
00129
00130 inline void GlBufferCudaPtr::Upload(const GLvoid* data, GLsizeiptr size_bytes, GLintptr offset)
00131 {
00132 Bind();
00133 glBufferSubData(buffer_type,offset,size_bytes, data);
00134 }
00135
00136 inline GlTextureCudaArray::GlTextureCudaArray(int width, int height, GLint internal_format)
00137 :GlTexture(width,height,internal_format)
00138 {
00139
00140 const cudaError_t err = cudaGraphicsGLRegisterImage(&cuda_res, tid, GL_TEXTURE_2D, cudaGraphicsMapFlagsNone);
00141 if( err != cudaSuccess )
00142 {
00143 std::cout << "cudaGraphicsGLRegisterImage failed: " << err << std::endl;
00144 }
00145 }
00146
00147 inline GlTextureCudaArray::~GlTextureCudaArray()
00148 {
00149 cudaGraphicsUnregisterResource(cuda_res);
00150 }
00151
00152 inline CudaScopedMappedPtr::CudaScopedMappedPtr(GlBufferCudaPtr& buffer)
00153 : res(buffer.cuda_res)
00154 {
00155 cudaGraphicsMapResources(1, &res, 0);
00156 }
00157
00158 inline CudaScopedMappedPtr::~CudaScopedMappedPtr()
00159 {
00160 cudaGraphicsUnmapResources(1, &res, 0);
00161 }
00162
00163 inline void* CudaScopedMappedPtr::operator*()
00164 {
00165 size_t num_bytes;
00166 void* d_ptr;
00167 cudaGraphicsResourceGetMappedPointer(&d_ptr,&num_bytes,res);
00168 return d_ptr;
00169 }
00170
00171 inline CudaScopedMappedArray::CudaScopedMappedArray(GlTextureCudaArray& tex)
00172 : res(tex.cuda_res)
00173 {
00174 cudaGraphicsMapResources(1, &res);
00175 }
00176
00177 inline CudaScopedMappedArray::~CudaScopedMappedArray()
00178 {
00179 cudaGraphicsUnmapResources(1, &res);
00180 }
00181
00182 inline cudaArray* CudaScopedMappedArray::operator*()
00183 {
00184 cudaArray* array;
00185 cudaGraphicsSubResourceGetMappedArray(&array, res, 0, 0);
00186 return array;
00187 }
00188
00189 inline void CopyPboToTex(const GlBufferCudaPtr& buffer, GlTexture& tex, GLenum buffer_layout, GLenum buffer_data_type )
00190 {
00191 buffer.Bind();
00192 tex.Bind();
00193 glTexImage2D(GL_TEXTURE_2D, 0, tex.internal_format, tex.width, tex.height, 0, buffer_layout, buffer_data_type, 0);
00194 buffer.Unbind();
00195 tex.Unbind();
00196 }
00197
00198 template<typename T>
00199 inline void CopyDevMemtoTex(T* d_img, size_t pitch, GlTextureCudaArray& tex )
00200 {
00201 CudaScopedMappedArray arr_tex(tex);
00202 cudaMemcpy2DToArray(*arr_tex, 0, 0, d_img, pitch, tex.width*sizeof(T), tex.height, cudaMemcpyDeviceToDevice );
00203 }
00204
00205 inline void swap(GlBufferCudaPtr& a, GlBufferCudaPtr& b)
00206 {
00207 std::swap(a.bo, b.bo);
00208 std::swap(a.cuda_res, b.cuda_res);
00209 std::swap(a.buffer_type, b.buffer_type);
00210 }
00211
00212
00213 }
00214
00215 #endif // PANGOLIN_CUDAGL_H