GLSL程序在某些iOS硬件上间歇性失败

GLSL程序在某些iOS硬件上间歇性失败,ios,ipad,opengl-es-2.0,glsles,Ios,Ipad,Opengl Es 2.0,Glsles,我遇到了一个问题,对片段着色器的更改会暂时中断渲染。着色器编译;编译步骤、链接步骤或glValidateProgram()没有错误条件或日志输出。但是对glDrawArrays()的后续调用会返回GL_无效的_操作,不会绘制任何内容,并且应用程序会变得非常缓慢或无响应 然而,当我从我的主要开发设备(iPad2)切换到其他硬件(iPhone5s和iPadMini)时,同样的代码运行得非常好。奇怪的是,如果我重新连接到iPad2,问题就消失了,我可以继续在该设备上开发着色器。同样的循环现在已经重复了

我遇到了一个问题,对片段着色器的更改会暂时中断渲染。着色器编译;编译步骤、链接步骤或glValidateProgram()没有错误条件或日志输出。但是对glDrawArrays()的后续调用会返回GL_无效的_操作,不会绘制任何内容,并且应用程序会变得非常缓慢或无响应

然而,当我从我的主要开发设备(iPad2)切换到其他硬件(iPhone5s和iPadMini)时,同样的代码运行得非常好。奇怪的是,如果我重新连接到iPad2,问题就消失了,我可以继续在该设备上开发着色器。同样的循环现在已经重复了好几次:我修改并向着色器添加了一些新代码,问题再次出现。我切换到更新的设备,代码运行正常,切换回iPad2,问题神秘地消失了(有时),我可以继续工作。一旦它再次开始工作,它似乎会继续工作。然而,有了下面的代码,我现在似乎被困在了一个解决方案没有帮助的地方

我的直觉(或希望)是,我的代码中的某些内容正在通过编译器,但在某种程度上是危险的,有些硬件接受它(A7和SGX 543),但有些不接受(SGX 535)。也许解决方法的间歇性本质只是一种转移注意力的手段。如果没有像这样的突然出现,我欢迎任何其他的故障排除建议

代码很长,所以我摘录了与这个问题的最新迭代相关的部分。以前的迭代只需要添加几行看似无害的代码

uniform highp vec3  vertexColors[3];

mediump vec3 hexagonLayer (highp float edge1, highp float edge2, int layer, mediump vec3 underColor, highp float opacity) {
    highp float opac = remap (length (faceP - vertexFacePositions[layer]), 0.0, edge1 * 3.0, 1.0, opacity);

    mediump vec3 shadowColor = pow (underColor, vec3 (2.0));
    highp float shadowOpacity = (1.0 - smoothstep (edge1, edge1 + SHADOW_WIDTH, 1.0 - trilinears[layer])) * SHADOW_OPACITY * opac;
    mediump vec3 color = mix (underColor, shadowColor, shadowOpacity);

    return mix (color, vertexColors[layer], (1.0 - smoothstep (edge1, edge2, 1.0 - trilinears[layer])) * opac);
}

至少部分地回答了我自己的问题。我的第一个错误是我的glValidateProgram()代码从未被调用。事实证明,我毕竟收到了一条错误消息,尽管这毫无帮助:

Validation Failed: Fragment program failed to compile with current context state.
Validation Failed: Vertex program failed to compile with current context state.
因此,第一课是,即使GL_COMPILE_状态和GL_LINK_状态都良好,并且两个日志都是静默的,显然也可能出现编译失败

多亏了来自的一条线索,我开始寻找不匹配的精度限定符,并且确信将所有mediump颜色更改为highp解决了这个问题。那是因为我声明我的制服是highp,然后在highp和mediump vec3之间混合()?(我缩短了问题中的代码以显示相关部分。)


对我来说,这可能会意外地在较新的硬件上工作,这是有道理的,因为我记得在某个地方读到,支持GLES-3的硬件将highp和mediump视为相同的位深度。我想确认一下这个猜测。

您可能已经考虑过了,但是间歇性的特性让我想知道这是否是您的目标C代码中的内存问题,可能是顶点缓冲区。您可以尝试在启用“Enable Guard Malloc”的情况下在模拟器上运行该应用程序。这通常要归咎于进动提示。