为什么2048年以后的纹理层中只有垃圾数据?

时间:2013-04-26 00:03:35

标签: opengl glsl textures opengl-4

我正在尝试使用最多8192个图层的texture_2d_array。但是在2048年之后的所有层都只包含垃圾数据(通过映射四边形上的各个层来测试纹理)。 使用

查询最大层数
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTexLayers);

为我的显卡(AMD 5770)返回8192,对于AMD 7850er则相同。我唯一可用的显卡是NVidia 480,仅支持2048层。

我使用以下代码创建纹理:

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, tex);

glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 7);

glTexStorage3D(GL_TEXTURE_2D_ARRAY, 8, GL_RGB8, 128, 128, 8192);
//glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 128, 128, 8192, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);

std::vector<char> image = readImage(testImagePath);

for (unsigned int i = 0; i < 8192; ++i)
{
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, 128, 128, 1, GL_RGB, GL_UNSIGNED_BYTE, image.data());
}

GLuint tLoc = glGetUniformLocation (program, "texArray");
glProgramUniform1i (program, tLoc, 0);

(这里https://mega.co.nz/#!FJ0gzIoJ!Kk0q_1xv9c7sCTi68mbKon1gDBUM1dgjrxoBJKTlj6U你可以找到该程序的简化版本)

我没有想法:

  1. 将glTexStorage3D更改为glTexImage3D - 无变化
  2. 使用基本/最高级别 - 无变化
  3. Min_Filter到GL_LINEAR - 无变化
  4. 生成mipmap(glGenerateMipmaps) - 无变化
  5. 将层的尺寸减小到例如4x4 - 没有变化
  6. 将层数减少到例如4096 - 没有变化
  7. 切换到AMD 7850 - 无变化
  8. 启用调试上下文 - 无错误
  9. 等。还有很多其他的东西
  10. 所以,它可能是驱动程序错误,驱动程序报告错误的GL_MAX_ARRAY_TEXTURE_LAYERS数字,但也许我错过了一些东西,其中一个人有一个想法。

    编辑:我知道这样的纹理会占用相当多的内存,即使我的显卡有很多可用的OpenGL也不能保证我可以分配它,但是我启用调试上下文时没有错误,特别是没有OUT_OF_MEMORY,我也尝试过每层大小4x4,这只是512kb

1 个答案:

答案 0 :(得分:4)

2件事:

1)128x128的8192纹理不会超过500MB的数据吗? (如果它是RGB而不是RGBA,则为400MB。)可能是由于碎片或其他问题,即使你的卡有那么多,OpenGL也无法分配那么多内存。

2)仅仅因为OpenGL说最大值是8192(或更大)并不意味着你保证在每种情况下都能使用那么多。例如,我的驱动程序声称该卡可以在一侧处理最大纹理大小8192。但是,如果我尝试创建一个32位浮点RGBA的4096x4096图像,它会失败,即使它只有268MB而且我有一个VR的VR。

glGetError()是否会返回任何错误?