问题描述
我正在使用 SDL2 和 OpenGL ES 为移动设备 (Android) 和 PC (Linux) 制作游戏 2.0.我为它写了一些着色器,它们在 PC 和小米上完美运行 Redmi Note 9 Pro,但不适用于我较旧的摩托罗拉 Moto G7 Play 手机。
经过一些测试,我设法想出了一个简短的顶点着色器来 重现问题:
#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]
被读取,在
它在示例中发生的顺序。对我来说它看起来像一个奇怪的司机或
编译器错误。
有没有人遇到过这种类型的问题?我还应该期待什么 是越野车?如何编写我的着色器来避免这个和类似的问题?和 特别是,为什么会发生这种情况?
你认为我应该在哪里报告它?谷歌?摩托罗拉?
谢谢
解决方法
我同意,这看起来像是一个驱动程序错误。显然,围绕 M 有很多优化空间,我想着色器编译器在这样做时会绊倒自己。
我要做的第一件事是检查设备是否有任何可用的操作系统更新。您可能会发现问题已经得到解决。
不幸的是,在 Android 上处理特定于驱动程序和设备的问题并不少见,您通常无法深入了解其原因。更糟糕的是,修复驱动程序错误的途径并不顺利。您应该向 GPU 制造商(在本例中为 Qualcomm)报告您的可重现案例,但很少有适当的错误报告系统,因此他们的开发者论坛是唯一的联系点。如果他们调查并修复(除非您有联系人,否则不太可能),那么他们将修复他们提供给硬件制造商的驱动程序。摩托罗拉可能会在下次发布设备操作系统更新时选择使用更新的驱动程序。如果他们这样做,那么蜂窝运营商可能决定向其用户提供更新。幸运的是,您的用户可能会更新。整个过程需要很长时间,并且修复程序可能无法到达所有受影响的最终用户。我相信 Google 意识到了瓶颈并计划解决它,但我不确定取得了多大进展。
最后,对开发者来说最好的办法是找到一种解决方法。在这种情况下,可能会简化代码并避免使用条件。也许运行离线优化步骤有助于减少着色器编译器错误的范围。
有时当我遇到特定于设备的问题时,我发现查看 this Chromium 使用的解决方法列表很有用。不过,我在列表中没有看到与此问题相关的任何内容。