【发布时间】:2017-12-21 20:57:22
【问题描述】:
我使用 C# 和 OpenTK 来访问 OpenGL API。我的项目使用曲面细分来渲染高度图。我的曲面细分控制着色器将一个正方形拆分为一个由 64 个正方形组成的网格,我的曲面细分评估着色器将垂直偏移添加到这些点。垂直偏移存储在一个统一的浮动缓冲区中,如下所示:
uniform float HeightmapBuffer[65 * 65];
当我在装有 AMD Radeon 8250 GPU 的笔记本电脑上运行项目时,一切正常。当我尝试在 Nvidia 显卡上运行它时,问题就开始了。我尝试了旧的 GT 430 和全新的 GTX 1060,但结果相同:
Tessellation evaluation info
----------------------------
0(13) : error C5041: cannot locate suitable resource to bind variable "HeightmapBuffer". Possibly large array.
当我研究这个问题时,我发现 GL_MAX_UNIFORM_BLOCK_SIZE 变量在 AMD 上返回 ~500MB,在两个 Nvidia 芯片上返回 65.54 kB。有点奇怪,因为我的数组实际上只使用了 16.9 kB,所以我什至不确定“块大小”是否真的限制了一个变量的大小。也许它限制了传递给一个着色器的所有制服的大小?即便如此,我还是不敢相信我的程序会使用 65 kB。
请注意,我也尝试通过使用纹理来采用“常见”方式,但我认为插值存在问题,因此当将两个相邻的高度图放在一起时,边界不匹配。另一边有一个统一的缓冲区数组,一切都很好。
那么GL_MAX_UNIFORM_BLOCK_SIZE的实际含义是什么?为什么 Nvidia GPU 上的这个值这么低?有没有其他方法可以将大数组传递给我的着色器?
【问题讨论】:
-
float制服实际上是vec4的大小,所以你有4 bytes * 4 * 65 * 65=67.6 KiB。 -
Hrm,我很难在 GL 规范中获取该信息,因此请谨慎对待。我可能记得 ES 2.0 规范。