情景
我正在创建两个相当大、大小相同的 OpenGL 3D 纹理。第一个是单通道 16 位纹理,第二个有四个通道,每个纹素 8 位。比我需要向 CUDA 注册他们两个。
我正在开发的应用程序是 32 位的。系统特性:Win 7 64bit,NVIDIA GeForce 540M 2GB
问题
当使用 512x512x391 或更大的纹理时,我的调用给cudaGraphicsGLRegisterImage
了我一个cudaErrorMemoryAllocation
,尽管这个返回值甚至不是可能的返回值列表的一部分,由cudaGraphicsGLRegisterImage
. 可以在第 94 页上找到此列表。以前没有执行过内存扩展操作。但是,它确实适用于较小的纹理,例如 512x512x71。
在调用之前查询可用的设备内存cudaGraphicsGLRegisterImage
会发现大约 1778 MB 是可用的。
审议
一种解释可能是返回值是某个先前调用的错误代码。我基本上可以通过在调用
cudaGetLastError
之前放置一个权利并检查它的返回值来消除这种可能性:它给了我一个.cudaGraphicsGLRegisterImage
cudaSuccess
我进行了一些计算。两个 3D 纹理所需的内存为:
(512 * 512 * 391) 纹素 * (4 通道 * 每纹素 1 字节 + 1 通道 * 每纹素 2 字节) = 586.5 MB
这并不多,尤其是当我的图形设备有 2 GB 的专用内存时。
我还检查了进程获取的总内存,以确保这不是 Win32-2GB 限制问题:根据任务管理器,总进程的内存大小约为 279 MB,就在
cudaGraphicsGLRegisterImage
调用。根据这个帖子,
cudaGraphicsRegisterImage
操作的内存成本应该非常低。
一些代码
获取两个 3D 纹理:
glTexImage3D( GL_TEXTURE_3D, 0, GL_INTENSITY16
, size.x, size.y, size.z
, 0, GL_RED, GL_UNSIGNED_SHORT, bufferPtr );
glTexImage3D( GL_TEXTURE_3D, 0, GL_RGBA8
, size.x, size.y, size.z
, 0, GL_RGB, GL_BYTE, nullptr );
我已经放弃了纹理生成和绑定以获得更好的概览。
使用 CUDA 进行纹理配准:
size_t free, total;
CHECK_CUDA( cudaMemGetInfo( &free, &total ) );
qDebug() << "Free Memory:" << free / ( 1024 * 1024 ) << "MB";
enum resourceIndices{ FIRST_RESOURCE = 0, SECOND_RESOURCE = 1 };
cudaGraphicsResource* resources[ 2 ];
CHECK_CUDA( cudaGetLastError() );
CHECK_CUDA( cudaGraphicsGLRegisterImage( &resources[ FIRST_RESOURCE ]
, firstTextureID
, GL_TEXTURE_3D
, cudaGraphicsRegisterFlagsReadOnly ) );
CHECK_CUDA( cudaGraphicsGLRegisterImage( &resources[ SECOND_RESOURCE ]
, secondTextureID
, GL_TEXTURE_3D
, cudaGraphicsRegisterFlagsSurfaceLoadStore ) );
宏CHECK_CUDA
只是检查返回值并抛出异常。cudaGraphicsGLRegisterImage
它在第一次调用时失败。