上传ASTC压缩纹理使用glCompressedTexImage2D花费太多时间?

Posted

技术标签:

【中文标题】上传ASTC压缩纹理使用glCompressedTexImage2D花费太多时间?【英文标题】:Upload ASTC compression texture use glCompressedTexImage2D cost too much time? 【发布时间】:2016-03-15 16:32:27 【问题描述】:

我正在开发一个 opengl 应用程序。我使用opengl函数:glCompressedTexImage2D(),以ASTC纹理压缩格式上传视频帧纹理。在GPU支持opengl扩展:GL_KHR_texture_compression_astc_ldr,压缩纹理格式为:GL_COMPRESSED_RGBA_ASTC_8x8_KHR的手机上运行良好,上传时间约为每帧2ms。

我想将应用程序移植到opengl 4.5和Nvidia GTX 750硬件的Windows平台上,发现上传成功,但是上传时间太长,每帧大约200ms~300ms。我查看硬件数据库:http://delphigl.de/glcapsviewer/listreports.php,发现 GTX 750 不支持 GL_KHR_texture_compression_astc_ldr 扩展。然后我使用了 Intel(R) HD Graphics 530,它支持 GL_KHR_texture_compression_astc_ldr 扩展,上传时间约为每帧 2ms。 所以我想知道为什么 Nvidia GTX 750 可以成功上传 ASTC 纹理但要花费这么多时间,有没有办法使用 Nvidia GTX 750 在正常时间(每帧 2 毫秒)上传 ASTC 纹理。Intel(R) HD Graphics 530无法支持复杂的 3D 应用。

这里是上传代码:

glCompressedTexImage2D(GL_TEXTURE_2D,
                                0,
                                compressed_data_internal_format,
                                xsize,
                                ysize,
                                0,
                                n_bytes_to_read,
                                astc_data_ptr);

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

【问题讨论】:

"上传时间太长,每帧200ms~300ms左右。"上传数据的“per-frame”是什么意思? 这意味着当我调用 glCompressedTexImage2D() 一次时,该函数的时间成本在支持 GL_KHR_texture_compression_astc_ldr 扩展的移动设备 GPU 和 Intel(R) HD Graphics 530 中约为 2ms。在Nvidia GTX 750中,时间大约是200ms~300ms,使用相同的数据上传。 【参考方案1】:

有没有办法使用 Nvidia GTX 750 在正常时间(每帧 2 毫秒)上传 ASTC 纹理

如果实现不公开 GL_KHR_texture_compression_astc_ldr 扩展,则该实现不支持 ASTC。因此,无论花费多少时间,您都无法将这些数据上传到它。

当您尝试以它不支持的格式分配纹理存储时,NVIDIA 的驱动程序应该出错了。但不管有没有,优化错误代码是没有意义的。查看错误代码的时序也没有意义。

在进行优化之前,您需要获取应该可以工作的代码。而你的不应该,除非支持该扩展。

【讨论】:

上传成功,画面呈现在屏幕上,glGetError()函数没有报错,为什么会这样? @francisyang:驱动程序错误。可能发生的是驱动程序正在解压缩您的图像数据。因此放缓。我会说NVIDIA的统一驱动模型可能是负责任的;代码的某些部分被开发为允许 ASTC 格式(也许是 Tegra),但没有硬件支持,它只是默认为解压缩。 所以你的意思是我只能使用 glCompressedTexImage2D() 将 ASTC 压缩纹理上传到支持 GL_KHR_texture_compression_astc_ldr 扩展和特定压缩纹理格式的 GPU。是否有任何链接或资料可以详细描述 GPU 上传 ASTC 纹理时的驱动程序过程?非常感谢您的帮助。 "有没有什么链接或者资料可以详细描述GPU上传ASTC纹理时的驱动过程?"我真的不明白你的意思。当您上传任何纹理时,所有应该发生的事情通常会发生:数据被复制到驱动程序分配的内存中。【参考方案2】:

去过那里.. 使用 ASTC 在移动平台上一切正常。 但是当我在 linux 中测试它时(使用 Nvidia Tesla T4 显卡),glCompressedTexImage2D 每帧花费 66 毫秒。 仅供参考,没有 glError 或渲染问题。

strack 显示下面的堆栈调用:

Thread 1 (Thread 0x7fe36885f840 (LWP 22683)):
#0  0x00007fe3619521a4 in ?? () from /lib64/libnvidia-eglcore.so.450.102.04
#1  0x00007fe361971d06 in ?? () from /lib64/libnvidia-eglcore.so.450.102.04
#2  0x00007fe361c7ff23 in ?? () from /lib64/libnvidia-eglcore.so.450.102.04
#3  0x00007fe361f4df01 in ?? () from /lib64/libnvidia-eglcore.so.450.102.04
#4  0x00007fe362010368 in ?? () from /lib64/libnvidia-eglcore.so.450.102.04
#5  0x00007fe362010ec9 in ?? () from /lib64/libnvidia-eglcore.so.450.102.04
#6  0x00007fe361c3814b in ?? () from /lib64/libnvidia-eglcore.so.450.102.04
#7  0x00007fe361c3f4b6 in ?? () from /lib64/libnvidia-eglcore.so.450.102.04
#8  0x0000000000594253 in glCompressedTexImage2D(width=720, height=1280, options=..., internelFormat=37808, bytesToRead=921600, data=0x5ecbe80) at /home/video-dev/Template/NESTImage/header/xxx.hpp:94

似乎驱动程序(/lib64/libnvidia-eglcore.so.450.102.04)处理了这些东西 可能是驱动解压 CPU 端的 ASTC 而不是 GPU。

【讨论】:

以上是关于上传ASTC压缩纹理使用glCompressedTexImage2D花费太多时间?的主要内容,如果未能解决你的问题,请参考以下文章

ASTC图片纹理压缩探讨

Unity纹理格式之Crunched

还原堆栈信息,分析地形系统使用ASTC格式的纹理导致Crash的问题

OpenGL RGB DXT1压缩纹理mipmap上传

unity-贴图压缩格式

unity-贴图压缩格式