OpenGL NVIDIA驱动GLSL顶点着色器数组循环访问编译错误问题
问题分析与验证结果
成因
这是老版本NVIDIA OpenGL驱动的着色器编译器缺陷:
- 你代码中的循环边界是编译期可确定的常量(N为宏定义常量,
N-2=4是固定值),但对应版本的NVIDIA编译器没有正确触发自动循环展开,反而生成了用通用寄存器做动态偏移的顶点属性数组寻址代码。 - 从报错的汇编输出可以看到,生成的动态寻址代码
vertex_attrib[R0.x + 32]超出了该版本驱动对顶点属性数组动态寻址的支持范围,进而抛出汇编编译错误。 - 手动展开循环后,所有数组访问的偏移都是编译期固定值,不需要动态寻址,因此可以正常编译。
规避方法
不需要手动展开循环,在循环前添加强制展开的编译指令即可:
#pragma optionNV(unroll all) for (int i = 0; i < N - 2; i++) n[i] = normalize(cross(v[i + 1] - v0, v[i + 2] - v0));
也可以升级到515及以上版本的NVIDIA正式驱动,该缺陷已经在后续版本中被修复。
AMD平台测试结果
在RX 6800XT、Adrenalin 23.4.1驱动、OpenGL 4.6环境下测试,你提供的复现代码可以正常编译运行,没有出现同类报错。AMD的着色器编译器可以正确识别该循环的常量边界并自动展开,不会生成有问题的动态寻址代码。
内容的提问来源于stack exchange,提问作者user14789259
相关产品推荐
相关产品推荐

