here is the scenario: I pass an 3D OpenGL Texture to CUDA by cudaBindTextureToArray transforming it with a non rigid transformation and writed it to a 3d surface and then I want to pass it by a texture to GLSL shader for volume rendering. and GLSL only knows texture id?how I use this 3d surface as an ordinary OpenGL texture?
pseudo code
craete a texture with opengl like this
glTexImage3D(GL_TEXTURE_3D, 0,............);
pass it to cuda
create and fill a surface with
cutilSafeCall(cudaBindSurfaceToArray(volumeTexOut, outTexture->content));
......
..
cutilSafeCall( cudaMalloc3DArray(&vol->content, &vol->channelDesc, dataSize, cudaArraySurfaceLoadStore ) );
after transformation,..
surf3Dwrite(short(voxel), volumeTexOut, sizeof(short)*x1,y1, z1);
and now i want to use this surface as an opengl Texture and pass it to GLSL
Update: The APIs suggested below are quite old and have been deprecated. Please see the current Graphics Interop APIs for CUDA
CUDA OpenGL interop is (unfortunately) a one-way API: to interoperate between CUDA and OpenGL you must allocate all memory needed in your GL code using OpenGL, and then bind it to CUDA arrays or device pointers in order to access it in CUDA. You cannot do the opposite (allocate memory with CUDA and access it from OpenGL). This goes for data that is either read or written by CUDA.
So for your output, you want to allocate the 3D texture in OpenGL, not with cudaMalloc3DArray()
. Then you want to call cudaGraphicsGLRegisterImage
with the cudaGraphicsRegisterFlagsSurfaceLoadStore
, and then bind a surface to the resulting array using cudaBindSurfaceToArray
. This is discussed in section 3.2.11.1 of the CUDA 4.2 CUDA C Programming Guide. The CUDA reference guide provides full documentation on the functions I mentioned.
Note that surface writes require a compute capability 2.0 or higher GPU.