为什么这个 GLSL 着色器在某些硬件上工作,但在其他硬件上却不工作?

Why does this GLSL shader works on some hardware but not on others?

我正在使用 SDL2 和 OpenGL ES 为手机 (Android) 和 PC (Linux) 制作游戏 2.0。我为它写了一些着色器,它们在 PC 和小米上完美运行 Redmi Note 9 Pro,但不在我的旧摩托罗拉 Moto G7 Play phone.

经过一些测试,我想出了一个简短的顶点着色器来 重现问题:

#version 100
/* 100 = OpenGL ES 2.0... */
attribute vec3 vertex;
void main()
{
    mat4 M = mat4(1.0);
    if (vertex.x == 0.0)    /* doesn't matter if it's true */
        M = mat4(1.0);  /* just set M to identity again */
#define FIX 0
#if FIX
    M[3].w = 1.0;       /* just set M[3][3] to 1.0 again */
#endif
    M[3].x = 0.5;       /* translate right */
    float w = M[3][3];  /* just read M[3][3] */
    gl_Position = M * vec4(vertex, 1.0);
}

着色器应该将多边形向右平移,这就是 发生在 PC 和 Redmi 上。然而,在 Moto G 上,一切都以 屏幕,除非 FIX 设置为 1。

有条件地触及M,然后读取M[3][3]时发生,在 它在示例中发生的顺序。对我来说,它看起来像一个奇怪的 driver 或 编译器错误。

有没有人遇到过此类问题?我还应该期待什么 是马车?我怎样才能编写我的着色器来避免这个和类似的问题?和 特别是,为什么会这样?

你认为我应该在哪里举报? Google?摩托罗拉?

谢谢 <3

我同意,这看起来像是驱动程序错误。显然围绕 M 有很大的优化空间,我想着色器编译器在这样做时会绊倒自己。

我要做的第一件事是检查设备是否有可用的 OS 更新。您可能会发现问题已得到解决。

不幸的是,处理特定于驱动程序和设备的问题在 Android 上并不少见,您通常无法深入了解其原因。更糟糕的是,修复驱动程序错误的途径并不顺利。您应该向 GPU 制造商(在本例中为 Qualcomm)报告您的可重现案例,但很少有厂商拥有适当的错误报告系统,因此他们的开发者论坛是唯一的联系点。如果他们调查并修复(除非您有联系人,否则不太可能),那么他们将修复他们提供给硬件制造商的驱动程序。摩托罗拉下次发布 OS 设备更新时可能会选择使用更新的驱动程序。如果他们这样做了,那么蜂窝运营商可能会决定向他们的用户提供更新。然后幸运的是你的用户可能会更新。整个过程需要很长时间,并且修复可能无法到达所有受影响的最终用户。我相信 Google 意识到瓶颈并计划解决它,但我不确定取得了多少进展。

最后,开发人员最好的办法是找到解决方法。在这种情况下,也许可以简化代码并避免使用条件语句。也许 运行 离线优化步骤可以帮助减少着色器编译器错误的范围。

有时,当我 运行 遇到设备特定问题时,我发现查看 Chromium 使用的 this 解决方法列表很有用。不过,我在列表中没有看到任何与此问题相关的内容。