glTexImage2D使用4G内存的nVidia显卡耗尽内存

时间:2014-04-10 14:30:18

标签: c++ opengl

一段代码:

// Some codes intializing 'transWidth' and 'transHeight' are ommitted
static vector<GLfloat> pixels;

printf("Alloc: %dx%dx4=%d floats\n", transWidth, transHeight, transWidth * transHeight * 4);
pixels.resize(transWidth * transHeight*4);
// Some codes modifying 'pixels'
// omitted

_CheckErrorGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, transWidth, transHeight, 0, GL_RGBA, GL_FLOAT, pixels.data());
_CheckErrorGL

_CheckErrorGL用于在必要时输出错误代码和描述:

#define _CheckErrorGL {\
    GLenum code;\
    if ((code = glGetError()) != GL_NO_ERROR)\
    {\
        printf("Error %d: %s\n", int(code), gluErrorString(code));\
        assert(false);\
    }\
}

此代码将执行多次。这是输出:

Ready for OpenGL 2.0
Alloc: 732x737x4=2157936 floats
Alloc: 3168x3224x4=40854528 floats
Alloc: 732x737x4=2157936 floats
Alloc: 3168x3224x4=40854528 floats
Error 1285: 内存不足
Alloc: 6561x1x4=26244 floats
Alloc: 732x737x4=2157936 floats
Alloc: 3168x3224x4=40854528 floats
Error 1285: 内存不足
Alloc: 732x737x4=2157936 floats
Alloc: 3168x3224x4=40854528 floats
Error 1285: 内存不足
Alloc: 6561x1x4=26244 floats

(&#39;内存不足&#39;表示&#39;内存不足&#39;。在发布模式下,assert只是(无效)0。)

浮点数为172102344,假设浮点数为4Bytes,则为656.5MiB。我的显卡是NVIDIA GeForce GTX 660 Ti,内存为4042MB。发生了什么事?

更新

我尝试了Andon和Surgey的建议。

以下是我的纹理参数:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);

仍然是相同的输出。但是当我在

中将RGBA32F更改为RGBA16FRGBA
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, transWidth, transHeight, 0, GL_RGBA, GL_FLOAT, pixels.data());

然后所有分配都成功。我在另一台配备NVIDIA GeForce GTX Titan(4095MB视频内存)的机器上试用了代码,但所有结果都是一样的。

注意:我使用dxdiag.exe来显示总视频内存。

2 个答案:

答案 0 :(得分:1)

看起来你已经达到了GPU特定的纹理大小限制。

尝试将内部格式GL_RGBA32F更改为GL_RGBA16F,然后更改为GL_RGBA,看看是否能够创建这些纹理。

答案 1 :(得分:1)

  

我的显卡是NVIDIA GeForce GTX 660 Ti,内存为4042MB。

4042 MiB号码包括GART(图形地址重映射表 - 系统共享内存) - 您的视频卡的实际专用内存有所不同。此外,在现代系统中,视频内存(无论是GART还是专用)在进程之间共享......您无需保证在各个应用程序中可以访问4042 MiB的存储空间。

由于您使用的是NV GPU,因此您可能会发现GL_NVX_gpu_memory_info扩展名很有用。


最后,您的纹理的实际存储要求并非您认为的那样。

创建GL纹理对象时,默认情况下有1000个纹理LOD,此代码生成不完整的纹理,因为您只为1000个LOD中的一个分配数据。您应该将GL_TEXTURE_MAX_LEVEL设置为 0 ,因为您只为单个LOD分配存储空间。

或者,您可以使用glTexStorage2D (...)来正确创建1 LOD的纹理,但这在OpenGL 2.0中不可用。