I’ve been following along with some guides online for linking an OpenGL texture to CUDA, but I seem to have run into a problem with “cudaBindTextureToArray.” Whenever I call that function, it returns an invalid texture arguments.
I have pasted my code that I am using to link the texture to a CUDA graphics resource, a CUDA array, and a CUDA texture reference. Line 65 is where my error occurs.
/// <summary>
/// Defines a 2D OpenGL texture's handle data.
/// </summary>
struct HandleData
{
GLuint GLHandle;
cudaGraphicsResource* CudaHandle;
cudaArray* CudaArray;
uchar4* TextureMemory;
};
// .............
// create the OpenGL texture
glGenTextures( 1, &( handle->GLHandle ) );
// initialize the texture to be the given size
glBindTexture( GL_TEXTURE_2D, handle->GLHandle );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_POINT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_POINT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glBindTexture( GL_TEXTURE_2D, 0 );
// create the CUDA graphics resource (this is fine)
cudaError_t err = cudaGraphicsGLRegisterImage( &( handle->CudaHandle ), handle->GLHandle, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsNone );
if ( err != cudaSuccess )
{
Logger::Log( "Failed to register GL texture. Reason: ", cudaGetErrorString( err ) );
delete handle;
return nullptr;
}
// map the CUDA graphics resource to a CUDA array (this is fine)
err = cudaGraphicsMapResources( 1, &( handle->CudaHandle ), nullptr );
if ( err != cudaSuccess )
{
Logger::Log( "Failed to map graphics resource to array. Reason: ", cudaGetErrorString( err ) );
delete handle;
return nullptr;
}
// get the mapped array (this is fine)
err = cudaGraphicsSubResourceGetMappedArray( &( handle->CudaArray ), handle->CudaHandle, 0, 0 );
if ( err != cudaSuccess )
{
Logger::Log( "Failed to get mapped array. Reason: ", cudaGetErrorString( err ) );
delete handle;
return nullptr;
}
// create the CUDA texture reference
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<uchar4>();
texture<uchar4, 2, cudaReadModeElementType> tex;
tex.addressMode[ 0 ] = cudaAddressModeClamp;
tex.addressMode[ 1 ] = cudaAddressModeClamp;
tex.filterMode = cudaFilterModePoint;
// bind the CUDA array to a texture object (THIS is where the error happens)
err = cudaBindTextureToArray( tex, handle->CudaArray, channelDesc );
if ( err != cudaSuccess )
{
Logger::Log( "Failed to bind texture to array. Reason: ", cudaGetErrorString( err ) );
delete handle;
return nullptr;
}
TLDR version:
- I create the OpenGL texture and set its filter/wrap mode to be point-clamp.
- I register the texture with cudaGraphicsGLRegisterImage, which is successful.
- I map the resource with cudaGraphicsMapResources, which is successful.
- I get the mapped array with cudaGraphicsSubResourceGetMappedArray, which is successful.
- I create the channel description and texture reference. Specifically "texture"
- I attempt to bind the texture to the array using cudaBindTextureToArray, which is where the code fails.
If somebody could help me with this, I would be very grateful.